Merge "Avoid calling getIconResult if recycle is called after request is queued" into sc-v2-dev
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index ddb20a1..8a05533 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -439,9 +439,9 @@
4 - rotationChange);
}
}
- // TODO(b/196637509): don't do this for immersive apps.
if (mDeviceProfile.isTaskbarPresentInApps) {
- bounds.bottom -= mDeviceProfile.taskbarSize;
+ // Animate to above the taskbar.
+ bounds.bottom -= target.contentInsets.bottom;
}
return bounds;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
index d0d7f31..106375a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
@@ -44,7 +44,7 @@
public float getSplitSelectTranslation(Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
int splitPosition = recentsView.getSplitPlaceholder().getActiveSplitStagePosition();
- if (!recentsView.shouldShiftThumbnailsForSplitSelect(splitPosition)) {
+ if (!recentsView.shouldShiftThumbnailsForSplitSelect()) {
return 0f;
}
PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 765480c..7e8b83e 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -202,6 +202,10 @@
@Override
public void onStateTransitionStart(RecentsState toState) {
+ if (toState == HOME) {
+ // Clean-up logic that occurs when recents is no longer in use/visible.
+ reset();
+ }
setOverviewStateEnabled(true);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.isFullScreen());
@@ -210,10 +214,6 @@
@Override
public void onStateTransitionComplete(RecentsState finalState) {
- if (finalState == HOME) {
- // Clean-up logic that occurs when recents is no longer in use/visible.
- reset();
- }
setOverlayEnabled(finalState == DEFAULT || finalState == MODAL_TASK);
setFreezeViewVisibility(false);
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 5ca5c94..715d30e 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -90,6 +90,10 @@
@Override
public void onStateTransitionStart(LauncherState toState) {
+ if (toState == NORMAL || toState == SPRING_LOADED) {
+ // Clean-up logic that occurs when recents is no longer in use/visible.
+ reset();
+ }
setOverviewStateEnabled(toState.overviewUi);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
@@ -98,10 +102,6 @@
@Override
public void onStateTransitionComplete(LauncherState finalState) {
- if (finalState == NORMAL || finalState == SPRING_LOADED) {
- // Clean-up logic that occurs when recents is no longer in use/visible.
- reset();
- }
setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK);
setFreezeViewVisibility(false);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index f7a9562..5a455c1 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -47,6 +47,8 @@
import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
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.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.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
@@ -1012,11 +1014,6 @@
}
}
- private boolean isLastGridTaskVisible() {
- TaskView lastTaskView = getLastGridTaskView();
- return lastTaskView != null && lastTaskView.isVisibleToUser();
- }
-
private TaskView getLastGridTaskView() {
IntArray topRowIdArray = getTopRowIdArray();
IntArray bottomRowIdArray = getBottomRowIdArray();
@@ -1898,6 +1895,7 @@
public void reset() {
setCurrentTask(-1);
+ mCurrentPageScrollDiff = 0;
mIgnoreResetTaskId = -1;
mTaskListChangeId = -1;
mFocusedTaskViewId = -1;
@@ -2756,7 +2754,13 @@
float dismissTranslationInterpolationEnd = 1;
boolean closeGapBetweenClearAll = false;
boolean isClearAllHidden = isClearAllHidden();
- if (showAsGrid && isLastGridTaskVisible()) {
+ boolean snapToLastTask = false;
+ boolean isLandscapeSplit =
+ mActivity.getDeviceProfile().isLandscape && isSplitSelectionActive();
+ boolean isSplitPlaceholderFirstInGrid = isSplitPlaceholderFirstInGrid();
+ boolean isSplitPlaceholderLastInGrid = isSplitPlaceholderLastInGrid();
+ TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null;
+ if (lastGridTaskView != null && lastGridTaskView.isVisibleToUser()) {
// After dismissal, animate translation of the remaining tasks to fill any gap left
// between the end of the grid and the clear all button. Only animate if the clear
// all button is visible or would become visible after dismissal.
@@ -2782,13 +2786,29 @@
longGridRowWidthDiff += mIsRtl ? -gapWidth : gapWidth;
if (isClearAllHidden) {
// If ClearAllButton isn't fully shown, snap to the last task.
- longGridRowWidthDiff += getSnapToLastTaskScrollDiff();
+ snapToLastTask = true;
}
} else {
// If only focused task will be left, snap to focused task instead.
longGridRowWidthDiff += getSnapToFocusedTaskScrollDiff(isClearAllHidden);
}
}
+ if (mClearAllButton.getAlpha() != 0f && isLandscapeSplit) {
+ // ClearAllButton will not be available in split select, snap to last task instead.
+ snapToLastTask = true;
+ }
+ if (snapToLastTask) {
+ longGridRowWidthDiff += getSnapToLastTaskScrollDiff();
+ if (isSplitPlaceholderLastInGrid) {
+ // Shift all the tasks to make space for split placeholder.
+ longGridRowWidthDiff += mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
+ }
+ } else if (isLandscapeSplit && getScrollForPage(mCurrentPage)
+ == getScrollForPage(indexOfChild(lastGridTaskView))) {
+ // Use last task as reference point for scroll diff and snapping calculation as it's
+ // the only invariant point in landscape split screen.
+ snapToLastTask = true;
+ }
// If we need to animate the grid to compensate the clear all gap, we split the second
// half of the dismiss pending animation (in which the non-dismissed tasks slide into
@@ -2945,6 +2965,20 @@
} else {
float primaryTranslation =
nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth;
+ if (isFocusedTaskDismissed && nextFocusedTaskView == null) {
+ // Moves less if focused task is not in scroll position.
+ int focusedTaskScroll = getScrollForPage(dismissedIndex);
+ int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
+ int focusedTaskScrollDiff = primaryScroll - focusedTaskScroll;
+ primaryTranslation +=
+ mIsRtl ? focusedTaskScrollDiff : -focusedTaskScrollDiff;
+ if (isSplitPlaceholderFirstInGrid) {
+ // Moves less if split placeholder is at the start.
+ primaryTranslation +=
+ mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
+ }
+ }
+
anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
mIsRtl ? primaryTranslation : -primaryTranslation,
clampToProgress(LINEAR, animationStartProgress,
@@ -2965,6 +2999,8 @@
mPendingAnimation = anim;
final TaskView finalNextFocusedTaskView = nextFocusedTaskView;
final boolean finalCloseGapBetweenClearAll = closeGapBetweenClearAll;
+ final boolean finalSnapToLastTask = snapToLastTask;
+ final boolean finalIsFocusedTaskDismissed = isFocusedTaskDismissed;
mPendingAnimation.addEndListener(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
@@ -3004,14 +3040,11 @@
int taskViewIdToSnapTo = -1;
if (showAsGrid) {
if (finalCloseGapBetweenClearAll) {
- if (taskCount > 2) {
+ if (finalSnapToLastTask) {
+ // Last task will be determined after removing dismissed task.
+ pageToSnapTo = -1;
+ } else if (taskCount > 2) {
pageToSnapTo = indexOfChild(mClearAllButton);
- if (isClearAllHidden) {
- int clearAllWidth = mOrientationHandler.getPrimarySize(
- mClearAllButton);
- mCurrentPageScrollDiff =
- isRtl() ? clearAllWidth : -clearAllWidth;
- }
} else if (isClearAllHidden) {
// Snap to focused task if clear all is hidden.
pageToSnapTo = 0;
@@ -3021,13 +3054,19 @@
// page's relative position as the order of indices change over time due
// to dismissals.
TaskView snappedTaskView = getTaskViewAt(mCurrentPage);
- if (snappedTaskView != null) {
+ boolean calculateScrollDiff = true;
+ if (snappedTaskView != null && !finalSnapToLastTask) {
if (snappedTaskView.getTaskViewId() == mFocusedTaskViewId) {
if (finalNextFocusedTaskView != null) {
taskViewIdToSnapTo =
finalNextFocusedTaskView.getTaskViewId();
- } else {
+ } else if (dismissedTaskViewId != mFocusedTaskViewId) {
taskViewIdToSnapTo = mFocusedTaskViewId;
+ } else {
+ // Won't focus next task in split select, so snap to the
+ // first task.
+ pageToSnapTo = 0;
+ calculateScrollDiff = false;
}
} else {
int snappedTaskViewId = snappedTaskView.getTaskViewId();
@@ -3059,10 +3098,20 @@
}
}
- int primaryScroll = mOrientationHandler.getPrimaryScroll(
- RecentsView.this);
- int currentPageScroll = getScrollForPage(pageToSnapTo);
- mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
+ if (calculateScrollDiff) {
+ int primaryScroll = mOrientationHandler.getPrimaryScroll(
+ RecentsView.this);
+ int currentPageScroll = getScrollForPage(mCurrentPage);
+ 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) {
pageToSnapTo--;
@@ -3075,10 +3124,14 @@
startHome();
} else {
// Update focus task and its size.
- if (finalNextFocusedTaskView != null) {
- mFocusedTaskViewId = finalNextFocusedTaskView.getTaskViewId();
- mTopRowIdSet.remove(mFocusedTaskViewId);
- finalNextFocusedTaskView.animateIconScaleAndDimIntoView();
+ if (finalIsFocusedTaskDismissed) {
+ if (finalNextFocusedTaskView != null) {
+ mFocusedTaskViewId = finalNextFocusedTaskView.getTaskViewId();
+ mTopRowIdSet.remove(mFocusedTaskViewId);
+ finalNextFocusedTaskView.animateIconScaleAndDimIntoView();
+ } else {
+ mFocusedTaskViewId = -1;
+ }
}
updateTaskSize(/*isTaskDismissal=*/ true);
updateChildTaskOrientations();
@@ -3091,7 +3144,7 @@
if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
TaskView taskView = getTaskViewAt(highestVisibleTaskIndex);
- boolean shouldRebalance = false;
+ boolean shouldRebalance;
int screenStart = mOrientationHandler.getPrimaryScroll(
RecentsView.this);
int taskStart = mOrientationHandler.getChildStart(taskView)
@@ -3122,9 +3175,12 @@
}
}
- // If snapping to another page due to indices rearranging, find the new
- // index after dismissal & rearrange using the task view id.
- if (taskViewIdToSnapTo != -1) {
+ if (finalSnapToLastTask) {
+ // If snapping to last task, find the last task after dismissal.
+ pageToSnapTo = indexOfChild(getLastGridTaskView());
+ } else if (taskViewIdToSnapTo != -1) {
+ // If snapping to another page due to indices rearranging, find
+ // the new index after dismissal & rearrange using the task view id.
pageToSnapTo = indexOfChild(
getTaskViewFromTaskViewId(taskViewIdToSnapTo));
}
@@ -3243,43 +3299,11 @@
}
/**
- * @return {@code true} if one of the task thumbnails would intersect/overlap with the
- * {@link #mFirstFloatingTaskView}
+ * Returns {@code true} if one of the task thumbnails would intersect/overlap with the
+ * {@link #mFirstFloatingTaskView}.
*/
- public boolean shouldShiftThumbnailsForSplitSelect(@StagePosition int stagePosition) {
- if (!mActivity.getDeviceProfile().isTablet) {
- // Never enough space on phones
- return true;
- } else if (!mActivity.getDeviceProfile().isLandscape) {
- return true;
- }
-
- Rect splitBounds = new Rect();
- // This acts as a best approximation on where the splitplaceholder view would be,
- // doesn't need to be exact necessarily. This also doesn't need to take translations
- // into account since placeholder view is not translated
- if (stagePosition == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT) {
- splitBounds.set(getWidth() - mSplitPlaceholderSize, 0, getWidth(), getHeight());
- } else {
- splitBounds.set(0, 0, mSplitPlaceholderSize, getHeight());
- }
- Rect taskBounds = new Rect();
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = getTaskViewAt(i);
- if (taskView == mSplitHiddenTaskView
- && !(showAsGrid() && taskView == getFocusedTaskView())) {
- // Case where the hidden task view would have overlapped w/ placeholder,
- // but because it's going to hide we don't care
- // TODO (b/187312247) edge case for thumbnails that are off screen but scroll on
- continue;
- }
- taskView.getBoundsOnScreen(taskBounds);
- if (Rect.intersects(taskBounds, splitBounds)) {
- return true;
- }
- }
- return false;
+ public boolean shouldShiftThumbnailsForSplitSelect() {
+ return !mActivity.getDeviceProfile().isTablet;
}
protected void onDismissAnimationEnds() {
@@ -3771,37 +3795,44 @@
* Apply scroll offset to children of RecentsView when entering split select.
*/
public void applySplitPrimaryScrollOffset() {
- if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()) {
- return;
- }
-
- @StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
- boolean shouldShiftThumbnailsForSplitSelect = shouldShiftThumbnailsForSplitSelect(
- position);
- boolean expandLeft = false;
- boolean expandRight = false;
- if (mIsRtl) {
- if (position == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
- && shouldShiftThumbnailsForSplitSelect) {
- expandLeft = true;
- } else if (position == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
- if (shouldShiftThumbnailsForSplitSelect) {
- expandRight = true;
- } else {
- expandLeft = true;
- }
- }
- } // TODO(b/200537659): Handle system RTL.
- if (expandRight) {
+ if (isSplitPlaceholderFirstInGrid()) {
for (int i = 0; i < getTaskViewCount(); i++) {
getTaskViewAt(i).setSplitScrollOffsetPrimary(mSplitPlaceholderSize);
}
- } else if (expandLeft) {
+ } else if (isSplitPlaceholderLastInGrid()) {
mClearAllButton.setSplitSelectScrollOffsetPrimary(-mSplitPlaceholderSize);
}
}
/**
+ * 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()) {
+ 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()) {
+ 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() {
@@ -4431,36 +4462,34 @@
@Override
protected int computeMinScroll() {
- if (getTaskViewCount() > 0) {
- if (mIsRtl) {
- // If we aren't showing the clear all button, use the rightmost task as the min
- // scroll.
- return getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
- getTaskViewAt(getTaskViewCount() - 1)) : indexOfChild(mClearAllButton));
- } else {
- TaskView focusedTaskView = mShowAsGridLastOnLayout ? getFocusedTaskView() : null;
- return getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
- : 0);
- }
+ if (getTaskViewCount() <= 0) {
+ return super.computeMinScroll();
}
- return super.computeMinScroll();
+
+ return getScrollForPage(mIsRtl ? getLastViewIndex() : getFirstViewIndex());
}
@Override
protected int computeMaxScroll() {
- if (getTaskViewCount() > 0) {
- if (mIsRtl) {
- TaskView focusedTaskView = mShowAsGridLastOnLayout ? getFocusedTaskView() : null;
- return getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
- : 0);
- } else {
- // If we aren't showing the clear all button, use the leftmost task as the min
- // scroll.
- return getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
- getTaskViewAt(getTaskViewCount() - 1)) : indexOfChild(mClearAllButton));
- }
+ if (getTaskViewCount() <= 0) {
+ return super.computeMaxScroll();
}
- return super.computeMaxScroll();
+
+ return getScrollForPage(mIsRtl ? getFirstViewIndex() : getLastViewIndex());
+ }
+
+ private int getFirstViewIndex() {
+ return mShowAsGridLastOnLayout && mFocusedTaskViewId != -1
+ ? indexOfChild(getFocusedTaskView())
+ : 0;
+ }
+
+ private int getLastViewIndex() {
+ return mDisallowScrollToClearAll
+ ? mShowAsGridLastOnLayout
+ ? indexOfChild(getLastGridTaskView())
+ : getTaskViewCount() - 1
+ : indexOfChild(mClearAllButton);
}
/**