Merge "Fix various animation issues when total width of grid tasks < screen width" into tm-qpr-dev am: a8c2ffc128 am: 2248a0e941 am: 888bc47918

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/21549707

Change-Id: I5ca6f950494afe48a5ea3661a9dac6f98bd365ae
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Alex Chau
2023-02-24 23:27:51 +00:00
committed by Automerger Merge Worker
5 changed files with 159 additions and 215 deletions
@@ -121,8 +121,7 @@ public final class RecentsViewStateController extends
private void handleSplitSelectionState(@NonNull LauncherState toState, private void handleSplitSelectionState(@NonNull LauncherState toState,
@NonNull PendingAnimation builder, boolean animate) { @NonNull PendingAnimation builder, boolean animate) {
if (toState != OVERVIEW_SPLIT_SELECT) { if (toState != OVERVIEW_SPLIT_SELECT) {
// Not going to split, nothing to do but ensure taskviews are at correct offset // Not going to split
mRecentsView.resetSplitPrimaryScrollOffset();
return; return;
} }
@@ -153,8 +152,6 @@ public final class RecentsViewStateController extends
as.start(); as.start();
as.end(); as.end();
} }
mRecentsView.applySplitPrimaryScrollOffset();
} }
private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config, private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config,
@@ -130,15 +130,9 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset( mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset(
TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION, TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
mActivity.getDeviceProfile()); mActivity.getDeviceProfile());
setter.setFloat(mRecentsView, taskViewsFloat.first, isSplitSelectionState(state)
? mRecentsView.getSplitSelectTranslation() : 0, LINEAR);
setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR); setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
if (isSplitSelectionState(state)) {
mRecentsView.applySplitPrimaryScrollOffset();
setter.setFloat(mRecentsView, taskViewsFloat.first,
mRecentsView.getSplitSelectTranslation(), LINEAR);
} else {
mRecentsView.resetSplitPrimaryScrollOffset();
setter.setFloat(mRecentsView, taskViewsFloat.first, 0, LINEAR);
}
} }
/** /**
@@ -67,7 +67,6 @@ public class ClearAllButton extends Button {
private float mGridTranslationPrimary; private float mGridTranslationPrimary;
private float mGridScrollOffset; private float mGridScrollOffset;
private float mScrollOffsetPrimary; private float mScrollOffsetPrimary;
private float mSplitSelectScrollOffsetPrimary;
private int mSidePadding; private int mSidePadding;
@@ -176,10 +175,6 @@ public class ClearAllButton extends Button {
mScrollOffsetPrimary = scrollOffsetPrimary; mScrollOffsetPrimary = scrollOffsetPrimary;
} }
public void setSplitSelectScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
}
public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
float scrollAdjustment = 0; float scrollAdjustment = 0;
if (fullscreenEnabled) { if (fullscreenEnabled) {
@@ -189,7 +184,6 @@ public class ClearAllButton extends Button {
scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset; scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset;
} }
scrollAdjustment += mScrollOffsetPrimary; scrollAdjustment += mScrollOffsetPrimary;
scrollAdjustment += mSplitSelectScrollOffsetPrimary;
return scrollAdjustment; return scrollAdjustment;
} }
@@ -53,8 +53,6 @@ import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLA
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK; import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA; import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
@@ -80,7 +78,6 @@ import android.animation.ValueAnimator;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.WindowConfiguration; import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.LocusId; import android.content.LocusId;
@@ -518,6 +515,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private float mTaskThumbnailSplashAlpha = 0; private float mTaskThumbnailSplashAlpha = 0;
private boolean mShowAsGridLastOnLayout = false; private boolean mShowAsGridLastOnLayout = false;
private final IntSet mTopRowIdSet = new IntSet(); private final IntSet mTopRowIdSet = new IntSet();
private int mClearAllShortTotalWidthTranslation = 0;
// The GestureEndTarget that is still in progress. // The GestureEndTarget that is still in progress.
@Nullable @Nullable
@@ -1234,21 +1232,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return clearAllScroll + (mIsRtl ? distance : -distance); return clearAllScroll + (mIsRtl ? distance : -distance);
} }
private int getSnapToFocusedTaskScrollDiff(boolean isClearAllHidden) {
int screenStart = mOrientationHandler.getPrimaryScroll(this);
int targetScroll = getScrollForPage(indexOfChild(getFocusedTaskView()));
if (!isClearAllHidden) {
int clearAllWidth = mOrientationHandler.getPrimarySize(mClearAllButton);
int taskGridHorizontalDiff = mLastComputedTaskSize.right - mLastComputedGridSize.right;
int clearAllFocusScrollDiff = taskGridHorizontalDiff - clearAllWidth;
targetScroll += mIsRtl ? clearAllFocusScrollDiff : -clearAllFocusScrollDiff;
}
return screenStart - targetScroll;
}
private boolean isTaskViewWithinBounds(TaskView tv, int start, int end) { private boolean isTaskViewWithinBounds(TaskView tv, int start, int end) {
int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment( int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
showAsFullscreen(), showAsGrid()); showAsGrid());
int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment( int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment(
showAsFullscreen())); showAsFullscreen()));
int taskEnd = taskStart + taskSize; int taskEnd = taskStart + taskSize;
@@ -1258,7 +1244,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private boolean isTaskViewFullyWithinBounds(TaskView tv, int start, int end) { private boolean isTaskViewFullyWithinBounds(TaskView tv, int start, int end) {
int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment( int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
showAsFullscreen(), showAsGrid()); showAsGrid());
int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment( int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment(
showAsFullscreen())); showAsFullscreen()));
int taskEnd = taskStart + taskSize; int taskEnd = taskStart + taskSize;
@@ -1565,7 +1551,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return; return;
} }
int currentTaskId = -1; int currentTaskId = INVALID_TASK_ID;
TaskView currentTaskView = getTaskViewAt(mCurrentPage); TaskView currentTaskView = getTaskViewAt(mCurrentPage);
if (currentTaskView != null && currentTaskView.getTask() != null) { if (currentTaskView != null && currentTaskView.getTask() != null) {
currentTaskId = currentTaskView.getTask().key.id; currentTaskId = currentTaskView.getTask().key.id;
@@ -1575,7 +1561,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
unloadVisibleTaskData(TaskView.FLAG_UPDATE_ALL); unloadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
TaskView ignoreResetTaskView = TaskView ignoreResetTaskView =
mIgnoreResetTaskId == -1 ? null : getTaskViewByTaskId(mIgnoreResetTaskId); mIgnoreResetTaskId == INVALID_TASK_ID
? null : getTaskViewByTaskId(mIgnoreResetTaskId);
// Save running task ID if it exists before rebinding all taskViews, otherwise the task from // Save running task ID if it exists before rebinding all taskViews, otherwise the task from
// the runningTaskView currently bound could get assigned to another TaskView // the runningTaskView currently bound could get assigned to another TaskView
@@ -1678,20 +1665,20 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
newFocusedTaskView = getTaskViewAt(1); newFocusedTaskView = getTaskViewAt(1);
} }
} }
mFocusedTaskViewId = newFocusedTaskView != null ? mFocusedTaskViewId =
newFocusedTaskView.getTaskViewId() : -1; newFocusedTaskView != null ? newFocusedTaskView.getTaskViewId() : INVALID_TASK_ID;
updateTaskSize(); updateTaskSize();
updateChildTaskOrientations(); updateChildTaskOrientations();
TaskView newRunningTaskView = null; TaskView newRunningTaskView = null;
if (runningTaskId != -1) { if (runningTaskId != INVALID_TASK_ID) {
// Update mRunningTaskViewId to be the new TaskView that was assigned by binding // Update mRunningTaskViewId to be the new TaskView that was assigned by binding
// the full list of tasks to taskViews // the full list of tasks to taskViews
newRunningTaskView = getTaskViewByTaskId(runningTaskId); newRunningTaskView = getTaskViewByTaskId(runningTaskId);
if (newRunningTaskView != null) { if (newRunningTaskView != null) {
mRunningTaskViewId = newRunningTaskView.getTaskViewId(); mRunningTaskViewId = newRunningTaskView.getTaskViewId();
} else { } else {
mRunningTaskViewId = -1; mRunningTaskViewId = INVALID_TASK_ID;
} }
} }
@@ -1699,7 +1686,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (mNextPage != INVALID_PAGE) { if (mNextPage != INVALID_PAGE) {
// Restore mCurrentPage but don't call setCurrentPage() as that clobbers the scroll. // Restore mCurrentPage but don't call setCurrentPage() as that clobbers the scroll.
mCurrentPage = previousCurrentPage; mCurrentPage = previousCurrentPage;
if (currentTaskId != -1) { if (currentTaskId != INVALID_TASK_ID) {
currentTaskView = getTaskViewByTaskId(currentTaskId); currentTaskView = getTaskViewByTaskId(currentTaskId);
if (currentTaskView != null) { if (currentTaskView != null) {
targetPage = indexOfChild(currentTaskView); targetPage = indexOfChild(currentTaskView);
@@ -1707,7 +1694,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
} }
} else { } else {
// Set the current page to the running task, but not if settling on new task. // Set the current page to the running task, but not if settling on new task.
if (runningTaskId != -1) { if (runningTaskId != INVALID_TASK_ID) {
targetPage = indexOfChild(newRunningTaskView); targetPage = indexOfChild(newRunningTaskView);
} else if (getTaskViewCount() > 0) { } else if (getTaskViewCount() > 0) {
TaskView taskView = requireTaskViewAt(0); TaskView taskView = requireTaskViewAt(0);
@@ -1733,12 +1720,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}); });
} }
if (mIgnoreResetTaskId != -1 && if (mIgnoreResetTaskId != INVALID_TASK_ID &&
getTaskViewByTaskId(mIgnoreResetTaskId) != ignoreResetTaskView) { getTaskViewByTaskId(mIgnoreResetTaskId) != ignoreResetTaskView) {
// If the taskView mapping is changing, do not preserve the visuals. Since we are // If the taskView mapping is changing, do not preserve the visuals. Since we are
// mostly preserving the first task, and new taskViews are added to the end, it should // mostly preserving the first task, and new taskViews are added to the end, it should
// generally map to the same task. // generally map to the same task.
mIgnoreResetTaskId = -1; mIgnoreResetTaskId = INVALID_TASK_ID;
} }
resetTaskVisuals(); resetTaskVisuals();
onTaskStackUpdated(); onTaskStackUpdated();
@@ -2478,8 +2465,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
for (TaskViewSimulator tvs : taskViewSimulators) { for (TaskViewSimulator tvs : taskViewSimulators) {
if (animatorSet == null) { if (animatorSet == null) {
setGridProgress(1); setGridProgress(1);
tvs.taskPrimaryTranslation.value = tvs.taskPrimaryTranslation.value = runningTaskPrimaryGridTranslation;
runningTaskPrimaryGridTranslation;
} else { } else {
animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1)); animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
animatorSet.play(tvs.taskPrimaryTranslation.animateToValue( animatorSet.play(tvs.taskPrimaryTranslation.animateToValue(
@@ -2721,7 +2707,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return; return;
} }
int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx; DeviceProfile deviceProfile = mActivity.getDeviceProfile();
int taskTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
int topRowWidth = 0; int topRowWidth = 0;
int bottomRowWidth = 0; int bottomRowWidth = 0;
@@ -2863,7 +2850,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
float snappedTaskGridTranslationX = 0; float snappedTaskGridTranslationX = 0;
if (snappedTaskView != null) { if (snappedTaskView != null) {
snappedTaskNonGridScrollAdjustment = snappedTaskView.getScrollAdjustment( snappedTaskNonGridScrollAdjustment = snappedTaskView.getScrollAdjustment(
/*fullscreenEnabled=*/true, /*gridEnabled=*/false); /*gridEnabled=*/false);
snappedTaskGridTranslationX = gridTranslations[snappedPage]; snappedTaskGridTranslationX = gridTranslations[snappedPage];
} }
@@ -2888,18 +2875,28 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// If the total width is shorter than one grid's width, move ClearAllButton further away // If the total width is shorter than one grid's width, move ClearAllButton further away
// accordingly. Update longRowWidth if ClearAllButton has been moved. // accordingly. Update longRowWidth if ClearAllButton has been moved.
float clearAllShortTotalCompensation = 0; float clearAllShortTotalWidthTranslation = 0;
int longRowWidth = Math.max(topRowWidth, bottomRowWidth); int longRowWidth = Math.max(topRowWidth, bottomRowWidth);
if (longRowWidth < mLastComputedGridSize.width()) { if (longRowWidth < mLastComputedGridSize.width()) {
float shortTotalCompensation = mLastComputedGridSize.width() - longRowWidth; mClearAllShortTotalWidthTranslation =
clearAllShortTotalCompensation = (mIsRtl
mIsRtl ? -shortTotalCompensation : shortTotalCompensation; ? mLastComputedTaskSize.right
longRowWidth = mLastComputedGridSize.width(); : deviceProfile.widthPx - mLastComputedTaskSize.left)
- longRowWidth - deviceProfile.overviewGridSideMargin;
clearAllShortTotalWidthTranslation = mIsRtl
? -mClearAllShortTotalWidthTranslation : mClearAllShortTotalWidthTranslation;
if (snappedTaskRowWidth == longRowWidth) {
// Updated snappedTaskRowWidth as well if it's same as longRowWidth.
snappedTaskRowWidth += mClearAllShortTotalWidthTranslation;
}
longRowWidth += mClearAllShortTotalWidthTranslation;
} else {
mClearAllShortTotalWidthTranslation = 0;
} }
float clearAllTotalTranslationX = float clearAllTotalTranslationX =
clearAllAccumulatedTranslation + clearAllShorterRowCompensation clearAllAccumulatedTranslation + clearAllShorterRowCompensation
+ clearAllShortTotalCompensation + snappedTaskNonGridScrollAdjustment; + clearAllShortTotalWidthTranslation + snappedTaskNonGridScrollAdjustment;
if (focusedTaskIndex < taskCount) { if (focusedTaskIndex < taskCount) {
// Shift by focused task's width and spacing if a task is focused. // Shift by focused task's width and spacing if a task is focused.
clearAllTotalTranslationX += clearAllTotalTranslationX +=
@@ -2909,11 +2906,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Make sure there are enough space between snapped page and ClearAllButton, for the case // Make sure there are enough space between snapped page and ClearAllButton, for the case
// of swiping up after quick switch. // of swiping up after quick switch.
if (snappedTaskView != null) { if (snappedTaskView != null) {
int distanceFromClearAll = longRowWidth - snappedTaskRowWidth + mPageSpacing; int distanceFromClearAll = longRowWidth - snappedTaskRowWidth;
// ClearAllButton should be off screen when snapped task is in its snapped position. // ClearAllButton should be off screen when snapped task is in its snapped position.
int minimumDistance = int minimumDistance =
mTaskWidth - snappedTaskView.getLayoutParams().width (mIsRtl
+ (mLastComputedGridSize.width() - mTaskWidth) / 2; ? mLastComputedTaskSize.left
: deviceProfile.widthPx - mLastComputedTaskSize.right)
- deviceProfile.overviewGridSideMargin - mPageSpacing
+ (mTaskWidth - snappedTaskView.getLayoutParams().width)
- mClearAllShortTotalWidthTranslation;
if (distanceFromClearAll < minimumDistance) { if (distanceFromClearAll < minimumDistance) {
int distanceDifference = minimumDistance - distanceFromClearAll; int distanceDifference = minimumDistance - distanceFromClearAll;
snappedTaskGridTranslationX += mIsRtl ? distanceDifference : -distanceDifference; snappedTaskGridTranslationX += mIsRtl ? distanceDifference : -distanceDifference;
@@ -3196,6 +3197,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Grid specific properties. // Grid specific properties.
boolean isFocusedTaskDismissed = false; boolean isFocusedTaskDismissed = false;
boolean isStagingFocusedTask = false;
TaskView nextFocusedTaskView = null; TaskView nextFocusedTaskView = null;
boolean nextFocusedTaskFromTop = false; boolean nextFocusedTaskFromTop = false;
float dismissedTaskWidth = 0; float dismissedTaskWidth = 0;
@@ -3210,26 +3212,30 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (showAsGrid) { if (showAsGrid) {
dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing; dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing;
isFocusedTaskDismissed = dismissedTaskViewId == mFocusedTaskViewId; isFocusedTaskDismissed = dismissedTaskViewId == mFocusedTaskViewId;
if (isFocusedTaskDismissed && !isSplitSelectionActive()) { if (isFocusedTaskDismissed) {
nextFocusedTaskFromTop = if (isSplitSelectionActive()) {
mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f; isStagingFocusedTask = true;
// Pick the next focused task from the preferred row. } else {
for (int i = 0; i < taskCount; i++) { nextFocusedTaskFromTop =
TaskView taskView = requireTaskViewAt(i); mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
if (taskView == dismissedTaskView) { // Pick the next focused task from the preferred row.
continue; for (int i = 0; i < taskCount; i++) {
TaskView taskView = requireTaskViewAt(i);
if (taskView == dismissedTaskView) {
continue;
}
boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId());
if ((nextFocusedTaskFromTop && isTopRow
|| (!nextFocusedTaskFromTop && !isTopRow))) {
nextFocusedTaskView = taskView;
break;
}
} }
boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId()); if (nextFocusedTaskView != null) {
if ((nextFocusedTaskFromTop && isTopRow nextFocusedTaskWidth =
|| (!nextFocusedTaskFromTop && !isTopRow))) { nextFocusedTaskView.getLayoutParams().width + mPageSpacing;
nextFocusedTaskView = taskView;
break;
} }
} }
if (nextFocusedTaskView != null) {
nextFocusedTaskWidth =
nextFocusedTaskView.getLayoutParams().width + mPageSpacing;
}
} }
} else { } else {
getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC); getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC);
@@ -3246,8 +3252,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
boolean snapToLastTask = false; boolean snapToLastTask = false;
boolean isLandscapeSplit = boolean isLandscapeSplit =
mActivity.getDeviceProfile().isLandscape && isSplitSelectionActive(); mActivity.getDeviceProfile().isLandscape && isSplitSelectionActive();
boolean isSplitPlaceholderFirstInGrid = isSplitPlaceholderFirstInGrid();
boolean isSplitPlaceholderLastInGrid = isSplitPlaceholderLastInGrid();
TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null; TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null;
int currentPageScroll = getScrollForPage(mCurrentPage); int currentPageScroll = getScrollForPage(mCurrentPage);
int lastGridTaskScroll = getScrollForPage(indexOfChild(lastGridTaskView)); int lastGridTaskScroll = getScrollForPage(indexOfChild(lastGridTaskView));
@@ -3264,37 +3268,61 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
boolean bottomRowLonger = bottomGridRowSize > topGridRowSize; boolean bottomRowLonger = bottomGridRowSize > topGridRowSize;
boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId); boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId);
boolean dismissedTaskFromBottom = !dismissedTaskFromTop && !isFocusedTaskDismissed; boolean dismissedTaskFromBottom = !dismissedTaskFromTop && !isFocusedTaskDismissed;
if (dismissedTaskFromTop || (isFocusedTaskDismissed && nextFocusedTaskFromTop)) {
topGridRowSize--;
}
if (dismissedTaskFromBottom || (isFocusedTaskDismissed && !nextFocusedTaskFromTop)) {
bottomGridRowSize--;
}
int longRowWidth = Math.max(topGridRowSize, bottomGridRowSize)
* (mLastComputedGridTaskSize.width() + mPageSpacing)
+ (isStagingFocusedTask ? 0 : mLastComputedTaskSize.width() + mPageSpacing);
float gapWidth = 0; float gapWidth = 0;
if ((topRowLonger && dismissedTaskFromTop) if ((topRowLonger && dismissedTaskFromTop)
|| (bottomRowLonger && dismissedTaskFromBottom)) { || (bottomRowLonger && dismissedTaskFromBottom)) {
gapWidth = dismissedTaskWidth; gapWidth = dismissedTaskWidth;
} else if ((topRowLonger && nextFocusedTaskFromTop) } else if (nextFocusedTaskView != null
|| (bottomRowLonger && !nextFocusedTaskFromTop)) { && ((topRowLonger && nextFocusedTaskFromTop)
|| (bottomRowLonger && !nextFocusedTaskFromTop))) {
gapWidth = nextFocusedTaskWidth; gapWidth = nextFocusedTaskWidth;
} }
if (gapWidth > 0) { if (gapWidth > 0) {
if (taskCount > 2) { if (mClearAllShortTotalWidthTranslation == 0) {
// Compensate the removed gap. // Compensate the removed gap if we don't already have shortTotalCompensation,
longGridRowWidthDiff += mIsRtl ? -gapWidth : gapWidth; // and adjust accordingly to the new shortTotalCompensation after dismiss.
if (isClearAllHidden) { int newClearAllShortTotalWidthTranslation = 0;
// If ClearAllButton isn't fully shown, snap to the last task. if (longRowWidth < mLastComputedGridSize.width()) {
snapToLastTask = true; DeviceProfile deviceProfile = mActivity.getDeviceProfile();
newClearAllShortTotalWidthTranslation =
(mIsRtl
? mLastComputedTaskSize.right
: deviceProfile.widthPx - mLastComputedTaskSize.left)
- longRowWidth - deviceProfile.overviewGridSideMargin;
} }
} else { float gapCompensation = gapWidth - newClearAllShortTotalWidthTranslation;
// If only focused task will be left, snap to focused task instead. longGridRowWidthDiff += mIsRtl ? -gapCompensation : gapCompensation;
longGridRowWidthDiff += getSnapToFocusedTaskScrollDiff(isClearAllHidden); }
if (isClearAllHidden) {
// If ClearAllButton isn't fully shown, snap to the last task.
snapToLastTask = true;
} }
} }
if (mClearAllButton.getAlpha() != 0f && isLandscapeSplit) { if (isLandscapeSplit && !isStagingFocusedTask) {
// ClearAllButton will not be available in split select, snap to last task instead. // LastTask's scroll is the minimum scroll in split select, if current scroll is
snapToLastTask = true; // beyond that, we'll need to snap to last task instead.
TaskView lastTask = getLastGridTaskView();
if (lastTask != null) {
int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
int lastTaskScroll = getScrollForPage(indexOfChild(lastTask));
if ((mIsRtl && primaryScroll < lastTaskScroll)
|| (!mIsRtl && primaryScroll > lastTaskScroll)) {
snapToLastTask = true;
}
}
} }
if (snapToLastTask) { if (snapToLastTask) {
longGridRowWidthDiff += getSnapToLastTaskScrollDiff(); longGridRowWidthDiff += getSnapToLastTaskScrollDiff();
if (isSplitPlaceholderLastInGrid) {
// Shift all the tasks to make space for split placeholder.
longGridRowWidthDiff += mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
}
} else if (isLandscapeSplit && currentPageSnapsToEndOfGrid) { } else if (isLandscapeSplit && currentPageSnapsToEndOfGrid) {
// Use last task as reference point for scroll diff and snapping calculation as it's // Use last task as reference point for scroll diff and snapping calculation as it's
// the only invariant point in landscape split screen. // the only invariant point in landscape split screen.
@@ -3452,8 +3480,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// dismissed index or next focused index. Offset successive task dismissal // dismissed index or next focused index. Offset successive task dismissal
// durations for a staggered effect. // durations for a staggered effect.
distanceFromDismissedTask++; distanceFromDismissedTask++;
boolean isStagingFocusedTask =
isFocusedTaskDismissed && nextFocusedTaskView == null;
int staggerColumn = isStagingFocusedTask int staggerColumn = isStagingFocusedTask
? (int) Math.ceil(distanceFromDismissedTask / 2f) ? (int) Math.ceil(distanceFromDismissedTask / 2f)
: distanceFromDismissedTask; : distanceFromDismissedTask;
@@ -3509,11 +3535,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int focusedTaskScrollDiff = primaryScroll - focusedTaskScroll; int focusedTaskScrollDiff = primaryScroll - focusedTaskScroll;
primaryTranslation += primaryTranslation +=
mIsRtl ? focusedTaskScrollDiff : -focusedTaskScrollDiff; mIsRtl ? focusedTaskScrollDiff : -focusedTaskScrollDiff;
if (isSplitPlaceholderFirstInGrid) {
// Moves less if split placeholder is at the start.
primaryTranslation +=
mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
}
} }
anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
@@ -3642,14 +3663,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
RecentsView.this); RecentsView.this);
int currentPageScroll = getScrollForPage(mCurrentPage); int currentPageScroll = getScrollForPage(mCurrentPage);
mCurrentPageScrollDiff = primaryScroll - currentPageScroll; mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
// Compensate for coordinate shift by split placeholder.
if (isSplitPlaceholderFirstInGrid && !finalSnapToLastTask) {
mCurrentPageScrollDiff +=
mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
} else if (isSplitPlaceholderLastInGrid && finalSnapToLastTask) {
mCurrentPageScrollDiff +=
mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
}
} }
} }
} else if (dismissedIndex < pageToSnapTo || pageToSnapTo == taskCount - 1) { } else if (dismissedIndex < pageToSnapTo || pageToSnapTo == taskCount - 1) {
@@ -3689,8 +3702,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int screenStart = mOrientationHandler.getPrimaryScroll( int screenStart = mOrientationHandler.getPrimaryScroll(
RecentsView.this); RecentsView.this);
int taskStart = mOrientationHandler.getChildStart(taskView) int taskStart = mOrientationHandler.getChildStart(taskView)
+ (int) taskView.getOffsetAdjustment(/*fullscreenEnabled=*/ + (int) taskView.getOffsetAdjustment(/*gridEnabled=*/ true);
false, /*gridEnabled=*/ true);
// Rebalance only if there is a maximum gap between the task and the // Rebalance only if there is a maximum gap between the task and the
// screen's edge; this ensures that rebalanced tasks are outside the // screen's edge; this ensures that rebalanced tasks are outside the
@@ -3853,14 +3865,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
REMOVE_TASK_WAIT_FOR_APP_STOP_MS); REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
} }
/**
* Returns {@code true} if one of the task thumbnails would intersect/overlap with the
* {@link #mFirstFloatingTaskView}.
*/
public boolean shouldShiftThumbnailsForSplitSelect() {
return !mActivity.getDeviceProfile().isTablet || !mActivity.getDeviceProfile().isLandscape;
}
protected void onDismissAnimationEnds() { protected void onDismissAnimationEnds() {
AccessibilityManagerCompat.sendDismissAnimationEndsEventToTest(getContext()); AccessibilityManagerCompat.sendDismissAnimationEndsEventToTest(getContext());
} }
@@ -4418,65 +4422,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
} }
} }
/**
* Apply scroll offset to children of RecentsView when entering split select.
*/
public void applySplitPrimaryScrollOffset() {
float taskSplitScrollOffsetPrimary = 0f;
float clearAllSplitScrollOffsetPrimar = 0f;
if (isSplitPlaceholderFirstInGrid()) {
taskSplitScrollOffsetPrimary = mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
} else if (isSplitPlaceholderLastInGrid()) {
clearAllSplitScrollOffsetPrimar =
mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
}
for (int i = 0; i < getTaskViewCount(); i++) {
requireTaskViewAt(i).setSplitScrollOffsetPrimary(taskSplitScrollOffsetPrimary);
}
mClearAllButton.setSplitSelectScrollOffsetPrimary(clearAllSplitScrollOffsetPrimar);
}
/**
* Returns if split placeholder is at the beginning of RecentsView. Always returns {@code false}
* if RecentsView is in portrait or RecentsView isn't shown as grid.
*/
private boolean isSplitPlaceholderFirstInGrid() {
if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()
|| !isSplitSelectionActive()) {
return false;
}
@StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
return mIsRtl
? position == STAGE_POSITION_BOTTOM_OR_RIGHT
: position == STAGE_POSITION_TOP_OR_LEFT;
}
/**
* Returns if split placeholder is at the end of RecentsView. Always returns {@code false} if
* RecentsView is in portrait or RecentsView isn't shown as grid.
*/
private boolean isSplitPlaceholderLastInGrid() {
if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()
|| !isSplitSelectionActive()) {
return false;
}
@StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
return mIsRtl
? position == STAGE_POSITION_TOP_OR_LEFT
: position == STAGE_POSITION_BOTTOM_OR_RIGHT;
}
/**
* Reset scroll offset on children of RecentsView when exiting split select.
*/
public void resetSplitPrimaryScrollOffset() {
for (int i = 0; i < getTaskViewCount(); i++) {
requireTaskViewAt(i).setSplitScrollOffsetPrimary(0);
}
mClearAllButton.setSplitSelectScrollOffsetPrimary(0);
}
/** /**
* Resets the visuals when exit modal state. * Resets the visuals when exit modal state.
*/ */
@@ -4685,14 +4630,29 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* Note that the translation can be its primary or secondary dimension. * Note that the translation can be its primary or secondary dimension.
*/ */
public float getSplitSelectTranslation() { public float getSplitSelectTranslation() {
int splitPosition = getSplitSelectController().getActiveSplitStagePosition(); DeviceProfile deviceProfile = mActivity.getDeviceProfile();
if (!shouldShiftThumbnailsForSplitSelect()) {
return 0f;
}
PagedOrientationHandler orientationHandler = getPagedOrientationHandler(); PagedOrientationHandler orientationHandler = getPagedOrientationHandler();
int splitPosition = getSplitSelectController().getActiveSplitStagePosition();
int splitPlaceholderSize =
mActivity.getResources().getDimensionPixelSize(R.dimen.split_placeholder_size);
int direction = orientationHandler.getSplitTranslationDirectionFactor( int direction = orientationHandler.getSplitTranslationDirectionFactor(
splitPosition, mActivity.getDeviceProfile()); splitPosition, deviceProfile);
return mActivity.getResources().getDimension(R.dimen.split_placeholder_size) * direction;
if (deviceProfile.isTablet && deviceProfile.isLandscape) {
// Only shift TaskViews if there is not enough space on the side of
// mLastComputedTaskSize to minimize motion.
int sideSpace = mIsRtl
? deviceProfile.widthPx - mLastComputedTaskSize.right
: mLastComputedTaskSize.left;
int extraSpace = splitPlaceholderSize + mPageSpacing - sideSpace;
if (extraSpace <= 0f) {
return 0f;
}
return extraSpace * direction;
}
return splitPlaceholderSize * direction;
} }
protected void onRotateInSplitSelectionState() { protected void onRotateInSplitSelectionState() {
@@ -4714,8 +4674,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (mSplitInstructionsView != null) { if (mSplitInstructionsView != null) {
mSplitInstructionsView.ensureProperRotation(); mSplitInstructionsView.ensureProperRotation();
} }
applySplitPrimaryScrollOffset();
} }
private void updateDeadZoneRects() { private void updateDeadZoneRects() {
@@ -5210,11 +5168,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
} }
private int getLastViewIndex() { private int getLastViewIndex() {
return mDisallowScrollToClearAll if (!mDisallowScrollToClearAll) {
? mShowAsGridLastOnLayout return indexOfChild(mClearAllButton);
? indexOfChild(getLastGridTaskView()) }
: getTaskViewCount() - 1
: indexOfChild(mClearAllButton); if (!mShowAsGridLastOnLayout) {
return getTaskViewCount() - 1;
}
TaskView lastGridTaskView = getLastGridTaskView();
if (lastGridTaskView != null) {
return indexOfChild(lastGridTaskView);
}
// Returns focus task if there are no grid tasks.
return indexOfChild(getFocusedTaskView());
} }
/** /**
@@ -5255,11 +5223,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
} }
final int taskCount = getTaskViewCount(); final int taskCount = getTaskViewCount();
int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
for (int i = 0; i < taskCount; i++) { for (int i = 0; i < taskCount; i++) {
TaskView taskView = requireTaskViewAt(i); TaskView taskView = requireTaskViewAt(i);
float scrollDiff = taskView.getScrollAdjustment(showAsFullscreen, showAsGrid); float scrollDiff = taskView.getScrollAdjustment(showAsGrid);
int pageScroll = newPageScrolls[i] + (int) scrollDiff; int pageScroll = newPageScrolls[i] + (int) scrollDiff;
int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
if ((mIsRtl && pageScroll < lastTaskScroll) if ((mIsRtl && pageScroll < lastTaskScroll)
|| (!mIsRtl && pageScroll > lastTaskScroll)) { || (!mIsRtl && pageScroll > lastTaskScroll)) {
pageScroll = lastTaskScroll; pageScroll = lastTaskScroll;
@@ -5283,8 +5251,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int childOffset = super.getChildOffset(index); int childOffset = super.getChildOffset(index);
View child = getChildAt(index); View child = getChildAt(index);
if (child instanceof TaskView) { if (child instanceof TaskView) {
childOffset += ((TaskView) child).getOffsetAdjustment(showAsFullscreen(), childOffset += ((TaskView) child).getOffsetAdjustment(showAsGrid());
showAsGrid());
} else if (child instanceof ClearAllButton) { } else if (child instanceof ClearAllButton) {
childOffset += ((ClearAllButton) child).getOffsetAdjustment(mOverviewFullscreenEnabled, childOffset += ((ClearAllButton) child).getOffsetAdjustment(mOverviewFullscreenEnabled,
showAsGrid()); showAsGrid());
@@ -5392,17 +5359,19 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int gridTaskSizeAndSpacing = mLastComputedGridTaskSize.width() + mPageSpacing; int gridTaskSizeAndSpacing = mLastComputedGridTaskSize.width() + mPageSpacing;
int positionDiff = gridTaskSizeAndSpacing * (lastGridTaskViewPosition - taskViewPosition); int positionDiff = gridTaskSizeAndSpacing * (lastGridTaskViewPosition - taskViewPosition);
int lastTaskEnd = (mIsRtl int taskEnd = getLastTaskEnd() + (mIsRtl ? positionDiff : -positionDiff);
? mLastComputedGridSize.left
: mLastComputedGridSize.right)
+ (mIsRtl ? mPageSpacing : -mPageSpacing);
int taskEnd = lastTaskEnd + (mIsRtl ? positionDiff : -positionDiff);
int normalTaskEnd = mIsRtl int normalTaskEnd = mIsRtl
? mLastComputedGridTaskSize.left ? mLastComputedGridTaskSize.left
: mLastComputedGridTaskSize.right; : mLastComputedGridTaskSize.right;
return taskEnd - normalTaskEnd; return taskEnd - normalTaskEnd;
} }
private int getLastTaskEnd() {
return mIsRtl
? mLastComputedGridSize.left + mPageSpacing + mClearAllShortTotalWidthTranslation
: mLastComputedGridSize.right - mPageSpacing - mClearAllShortTotalWidthTranslation;
}
private int getPositionInRow( private int getPositionInRow(
TaskView taskView, IntArray topRowIdArray, IntArray bottomRowIdArray) { TaskView taskView, IntArray topRowIdArray, IntArray bottomRowIdArray) {
int position = topRowIdArray.indexOf(taskView.getTaskViewId()); int position = topRowIdArray.indexOf(taskView.getTaskViewId());
@@ -5702,14 +5671,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
taskView = getTaskViewAt(--targetPage); taskView = getTaskViewAt(--targetPage);
} }
// Target a scroll where targetPage is on left of screen but still fully visible. // Target a scroll where targetPage is on left of screen but still fully visible.
int lastTaskEnd = (mIsRtl
? mLastComputedGridSize.left
: mLastComputedGridSize.right)
+ (mIsRtl ? mPageSpacing : -mPageSpacing);
int normalTaskEnd = mIsRtl int normalTaskEnd = mIsRtl
? mLastComputedGridTaskSize.left ? mLastComputedGridTaskSize.left
: mLastComputedGridTaskSize.right; : mLastComputedGridTaskSize.right;
int targetScroll = getScrollForPage(targetPage) + normalTaskEnd - lastTaskEnd; int targetScroll = getScrollForPage(targetPage) + normalTaskEnd - getLastTaskEnd();
// Find a page that is close to targetScroll while not over it. // Find a page that is close to targetScroll while not over it.
while (targetPage - 1 >= 0 while (targetPage - 1 >= 0
&& (mIsRtl && (mIsRtl
@@ -375,7 +375,6 @@ public class TaskView extends FrameLayout implements Reusable {
// Used when in SplitScreenSelectState // Used when in SplitScreenSelectState
private float mSplitSelectTranslationY; private float mSplitSelectTranslationY;
private float mSplitSelectTranslationX; private float mSplitSelectTranslationX;
private float mSplitSelectScrollOffsetPrimary;
@Nullable @Nullable
private ObjectAnimator mIconAndDimAnimator; private ObjectAnimator mIconAndDimAnimator;
@@ -1297,10 +1296,6 @@ public class TaskView extends FrameLayout implements Reusable {
applyTranslationY(); applyTranslationY();
} }
public void setSplitScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
}
private void setDismissTranslationX(float x) { private void setDismissTranslationX(float x) {
mDismissTranslationX = x; mDismissTranslationX = x;
applyTranslationX(); applyTranslationX();
@@ -1364,19 +1359,18 @@ public class TaskView extends FrameLayout implements Reusable {
applyTranslationX(); applyTranslationX();
} }
public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { public float getScrollAdjustment(boolean gridEnabled) {
float scrollAdjustment = 0; float scrollAdjustment = 0;
if (gridEnabled) { if (gridEnabled) {
scrollAdjustment += mGridTranslationX; scrollAdjustment += mGridTranslationX;
} else { } else {
scrollAdjustment += getPrimaryNonGridTranslationProperty().get(this); scrollAdjustment += getPrimaryNonGridTranslationProperty().get(this);
} }
scrollAdjustment += mSplitSelectScrollOffsetPrimary;
return scrollAdjustment; return scrollAdjustment;
} }
public float getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { public float getOffsetAdjustment(boolean gridEnabled) {
return getScrollAdjustment(fullscreenEnabled, gridEnabled); return getScrollAdjustment(gridEnabled);
} }
public float getSizeAdjustment(boolean fullscreenEnabled) { public float getSizeAdjustment(boolean fullscreenEnabled) {