Refactoring RecentsView to handle non-TaskViews

Change-Id: I0bc28ef670a1dad9a3912ca5360c9bab18afd4b2
This commit is contained in:
Sreyas
2019-08-13 16:43:21 -07:00
parent d61f73d935
commit 78010c1958
9 changed files with 136 additions and 70 deletions

View File

@@ -19,7 +19,6 @@ import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.LayoutUtils;
@@ -69,8 +68,16 @@ public class BackgroundAppState extends OverviewState {
if (taskCount == 0) {
return super.getOverviewScaleAndTranslation(launcher);
}
TaskView dummyTask = recentsView.getTaskViewAt(Utilities.boundToRange(
recentsView.getCurrentPage(), 0, taskCount - 1));
TaskView dummyTask;
if (recentsView.getCurrentPage() >= 0) {
if (recentsView.getCurrentPage() <= taskCount - 1) {
dummyTask = recentsView.getCurrentPageTaskView();
} else {
dummyTask = recentsView.getTaskViewAt(taskCount - 1);
}
} else {
dummyTask = recentsView.getTaskViewAt(0);
}
return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask)
.getScaleAndTranslation();
}

View File

@@ -47,9 +47,9 @@ public final class PortraitOverviewStateTouchHelper {
* @return true if we should intercept the motion event
*/
boolean canInterceptTouch(MotionEvent ev) {
if (mRecentsView.getChildCount() > 0) {
if (mRecentsView.getTaskViewCount() > 0) {
// Allow swiping up in the gap between the hotseat and overview.
return ev.getY() >= mRecentsView.getChildAt(0).getBottom();
return ev.getY() >= mRecentsView.getTaskViewAt(0).getBottom();
} else {
// If there are no tasks, we only intercept if we're below the hotseat height.
return isTouchOverHotseat(mLauncher, ev);
@@ -63,7 +63,7 @@ public final class PortraitOverviewStateTouchHelper {
* @return true if going back should take the user to the currently running task
*/
boolean shouldSwipeDownReturnToApp() {
TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getNextPage());
TaskView taskView = mRecentsView.getNextPageTaskView();
return taskView != null && mRecentsView.shouldSwipeDownLaunchApp();
}
@@ -76,7 +76,7 @@ public final class PortraitOverviewStateTouchHelper {
*/
PendingAnimation createSwipeDownToTaskAppAnimation(long duration) {
mRecentsView.setCurrentPage(mRecentsView.getPageNearestToCenterOfScreen());
TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getCurrentPage());
TaskView taskView = mRecentsView.getCurrentPageTaskView();
if (taskView == null) {
throw new IllegalStateException("There is no task view to animate to.");
}

View File

@@ -50,7 +50,6 @@ import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.QuickStepContract;
/**
* Handles quick switching to a recent task from the home screen.

View File

@@ -227,10 +227,10 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
// Launch the task user scrolled to (mRecentsView.getNextPage()).
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// We finish recents animation inside launchTask() when live tile is enabled.
mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */,
mRecentsView.getNextPageTaskView().launchTask(false /* animate */,
true /* freezeTaskList */);
} else {
int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id;
int taskId = mRecentsView.getNextPageTaskView().getTask().key.id;
mFinishingRecentsAnimationForNewTaskId = taskId;
mRecentsAnimationWrapper.finish(true /* toRecents */, () -> {
if (!mCanceled) {

View File

@@ -268,7 +268,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
int runningTaskIndex = recentsView.getRunningTaskIndex();
if (runningTaskIndex == 0) {
if (runningTaskIndex == recentsView.getTaskViewStartIndex()) {
// If we are on the first task (we haven't quick switched), translate recents in
// from the side. Calculate the start translation based on current scale/scroll.
float currScale = recentsView.getScaleX();
@@ -351,8 +351,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
private void playScaleDownAnim(AnimatorSet anim, Launcher launcher, LauncherState fromState,
LauncherState endState) {
RecentsView recentsView = launcher.getOverviewPanel();
TaskView v = recentsView.getTaskViewAt(recentsView.getCurrentPage());
if (v == null) {
if (recentsView.getCurrentPageTaskView() == null) {
return;
}
@@ -380,7 +379,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
// recents as a whole needs to translate further to keep up with the app window.
TaskView runningTaskView = recentsView.getRunningTaskView();
if (runningTaskView == null) {
runningTaskView = recentsView.getTaskViewAt(recentsView.getCurrentPage());
runningTaskView = recentsView.getCurrentPageTaskView();
}
TimeInterpolator oldInterpolator = translateY.getInterpolator();
Rect fallbackInsets = launcher.getDeviceProfile().getInsets();

View File

@@ -109,7 +109,7 @@ public class OverviewCommandHelper {
TaskView taskView = rv.getNextTaskView();
if (taskView == null) {
if (rv.getTaskViewCount() > 0) {
taskView = (TaskView) rv.getPageAt(0);
taskView = rv.getTaskViewAt(0);
taskView.requestFocus();
} else {
rv.requestFocus();

View File

@@ -479,8 +479,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask;
if (animate) {
// Only animate if an adjacent task view is visible on screen.
TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1);
TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1);
TaskView adjacentTask1 = mRecentsView.getNextTaskView();
TaskView adjacentTask2 = mRecentsView.getPreviousTaskView();
float prevTranslationX = mRecentsView.getTranslationX();
mRecentsView.setTranslationX(0);
animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT))
@@ -590,8 +590,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
*/
private void updateSysUiFlags(float windowProgress) {
if (mRecentsView != null) {
TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView
.getPageNearestToCenterOfScreen());
TaskView centermostTask = mRecentsView.getTaskViewNearestToCenterOfScreen();
int centermostTaskFlags = centermostTask == null ? 0
: centermostTask.getThumbnail().getSysUiStatusNavFlags();
boolean useHomeScreenFlags = windowProgress > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD;

View File

@@ -176,7 +176,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
protected void applyLoadPlan(ArrayList<Task> tasks) {
// When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
// track the index of the next task appropriately, as it we are switching on any other app.
// track the index of the next task appropriately, as if we are switching on any other app.
if (mRunningTaskInfo != null && mRunningTaskInfo.taskId == mRunningTaskId) {
// Check if the task list has running task
boolean found = false;

View File

@@ -306,6 +306,9 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private Layout mEmptyTextLayout;
private LiveTileOverlay mLiveTileOverlay;
// Keeps track of the index where the first TaskView should be
private int mTaskViewStartIndex = 0;
private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
(inMultiWindowMode) -> {
if (!inMultiWindowMode && mOverviewStateEnabled) {
@@ -329,7 +332,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
.inflate(R.layout.overview_clear_all_button, this, false);
mClearAllButton.setOnClickListener(this::dismissAllTasks);
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
10 /* initial size */);
@@ -430,7 +432,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
super.onViewRemoved(child);
// Clear the task data for the removed child if it was visible
if (child != mClearAllButton) {
if (child instanceof TaskView) {
TaskView taskView = (TaskView) child;
mHasVisibleTaskData.delete(taskView.getTask().key.id);
mTaskViewPool.recycle(taskView);
@@ -444,7 +446,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public TaskView getTaskView(int taskId) {
for (int i = 0; i < getTaskViewCount(); i++) {
TaskView tv = (TaskView) getChildAt(i);
TaskView tv = getTaskViewAt(i);
if (tv.getTask() != null && tv.getTask().key != null && tv.getTask().key.id == taskId) {
return tv;
}
@@ -536,28 +538,26 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
if (tasks == null || tasks.isEmpty()) {
removeAllViews();
removeTasksViewsAndClearAllButton();
onTaskStackUpdated();
return;
}
int oldChildCount = getChildCount();
// Unload existing visible task data
unloadVisibleTaskData();
TaskView ignoreRestTaskView =
TaskView ignoreResetTaskView =
mIgnoreResetTaskId == -1 ? null : getTaskView(mIgnoreResetTaskId);
final int requiredTaskCount = tasks.size();
if (getTaskViewCount() != requiredTaskCount) {
if (oldChildCount > 0) {
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
}
for (int i = getChildCount(); i < requiredTaskCount; i++) {
for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
addView(mTaskViewPool.getView());
}
while (getChildCount() > requiredTaskCount) {
while (getTaskViewCount() > requiredTaskCount) {
removeView(getChildAt(getChildCount() - 1));
}
if (requiredTaskCount > 0) {
@@ -567,17 +567,20 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
// Rebind and reset all task views
for (int i = requiredTaskCount - 1; i >= 0; i--) {
final int pageIndex = requiredTaskCount - i - 1;
final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
final Task task = tasks.get(i);
final TaskView taskView = (TaskView) getChildAt(pageIndex);
taskView.bind(task);
}
TaskView runningTaskView = getRunningTaskView();
if (runningTaskView != null) {
setCurrentPage(indexOfChild(runningTaskView));
} else if (getTaskViewCount() > 0) {
setCurrentPage(indexOfChild(getTaskViewAt(0)));
}
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreRestTaskView) {
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
// 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
// generally map to the same task.
@@ -588,17 +591,28 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
updateEnabledOverlays();
}
private void removeTasksViewsAndClearAllButton() {
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
removeView(getTaskViewAt(i));
}
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
}
}
public int getTaskViewCount() {
// Account for the clear all button.
int childCount = getChildCount();
return childCount == 0 ? 0 : childCount - 1;
int taskViewCount = getChildCount() - mTaskViewStartIndex;
if (indexOfChild(mClearAllButton) != -1) {
taskViewCount--;
}
return taskViewCount;
}
protected void onTaskStackUpdated() { }
public void resetTaskVisuals() {
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
TaskView taskView = (TaskView) getChildAt(i);
TaskView taskView = getTaskViewAt(i);
if (mIgnoreResetTaskId != taskView.getTask().key.id) {
taskView.resetVisualProperties();
taskView.setStableAlpha(mContentAlpha);
@@ -704,7 +718,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
/**
* Iterates through all thet asks, and loads the associated task data for newly visible tasks,
* Iterates through all the tasks, and loads the associated task data for newly visible tasks,
* and unloads the associated task data for tasks that are no longer visible.
*/
public void loadVisibleTaskData() {
@@ -715,15 +729,16 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
int centerPageIndex = getPageNearestToCenterOfScreen();
int numChildren = getTaskViewCount();
int numChildren = getChildCount();
int lower = Math.max(0, centerPageIndex - 2);
int upper = Math.min(centerPageIndex + 2, numChildren - 1);
// Update the task data for the in/visible children
for (int i = 0; i < numChildren; i++) {
TaskView taskView = (TaskView) getChildAt(i);
for (int i = 0; i < getTaskViewCount(); i++) {
TaskView taskView = getTaskViewAt(i);
Task task = taskView.getTask();
boolean visible = lower <= i && i <= upper;
int index = indexOfChild(taskView);
boolean visible = lower <= index && index <= upper;
if (visible) {
if (task == mTmpRunningTask) {
// Skip loading if this is the task that we are animating into
@@ -798,6 +813,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return tv == null ? -1 : indexOfChild(tv);
}
public int getTaskViewStartIndex() {
return mTaskViewStartIndex;
}
/**
* Reloads the view if anything in recents changed.
*/
@@ -853,10 +872,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
*/
public void showCurrentTask(int runningTaskId) {
if (getTaskView(runningTaskId) == null) {
boolean wasEmpty = getChildCount() == 0;
boolean wasEmpty = getTaskViewCount() == 0;
// Add an empty view for now until the task plan is loaded and applied
final TaskView taskView = mTaskViewPool.getView();
addView(taskView, 0);
addView(taskView, mTaskViewStartIndex);
if (wasEmpty) {
addView(mClearAllButton);
}
@@ -922,14 +941,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
if (runningTaskView == null) {
// Launch the first task
if (getTaskViewCount() > 0) {
getTaskViewAt(0).launchTask(true /* animate */);
getTaskViewAt(0).launchTask(true);
}
} else {
TaskView nextTaskView = getNextTaskView();
if (nextTaskView != null) {
nextTaskView.launchTask(true /* animate */);
if (getNextTaskView() != null) {
getNextTaskView().launchTask(true);
} else {
runningTaskView.launchTask(true /* animate */);
runningTaskView.launchTask(true);
}
}
}
@@ -1189,7 +1207,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
int count = getTaskViewCount();
for (int i = 0; i < count; i++) {
addDismissedTaskAnimations(getChildAt(i), anim, duration);
addDismissedTaskAnimations(getTaskViewAt(i), anim, duration);
}
mPendingAnimation = pendingAnimation;
@@ -1197,7 +1215,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
if (onEndListener.isSuccess) {
// Remove all the task views now
ActivityManagerWrapper.getInstance().removeAllRecentTasks();
removeAllViews();
removeTasksViewsAndClearAllButton();
startHome();
}
mPendingAnimation = null;
@@ -1344,26 +1362,50 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
child.setAlpha(mContentAlpha);
}
/**
* @return The most recent task that is older than the currently running task. If there is
* currently no running task or there is no task older than it, then return null.
*/
@Nullable
public TaskView getNextTaskView() {
TaskView runningTaskView = getRunningTaskView();
if (runningTaskView == null) {
return null;
}
return getTaskViewAt(indexOfChild(runningTaskView) + 1);
return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() + 1);
}
@Nullable
public TaskView getPreviousTaskView() {
return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() - 1);
}
@Nullable
public TaskView getCurrentPageTaskView() {
return getTaskViewAtByAbsoluteIndex(getCurrentPage());
}
@Nullable
public TaskView getNextPageTaskView() {
return getTaskViewAtByAbsoluteIndex(getNextPage());
}
@Nullable
public TaskView getTaskViewNearestToCenterOfScreen() {
return getTaskViewAtByAbsoluteIndex(getPageNearestToCenterOfScreen());
}
/**
* Returns null instead of indexOutOfBoundsError when index is not in range
*/
@Nullable
public TaskView getTaskViewAt(int index) {
View child = getChildAt(index);
return child == mClearAllButton ? null : (TaskView) child;
return getTaskViewAtByAbsoluteIndex(index + mTaskViewStartIndex);
}
@Nullable
private TaskView getTaskViewAtByAbsoluteIndex(int index) {
if (index < getChildCount() && index >= 0) {
View child = getChildAt(index);
return child instanceof TaskView ? (TaskView) child : null;
}
return null;
}
public void updateEmptyMessage() {
boolean isEmpty = getChildCount() == 0;
boolean isEmpty = getTaskViewCount() == 0;
boolean hasSizeChanged = mLastMeasureSize.x != getWidth()
|| mLastMeasureSize.y != getHeight();
if (isEmpty == mShowEmptyMessage && !hasSizeChanged) {
@@ -1497,7 +1539,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
throw new IllegalStateException("Another pending animation is still running");
}
int count = getChildCount();
int count = getTaskViewCount();
if (count == 0) {
return new PendingAnimation(new AnimatorSet());
}
@@ -1670,18 +1712,38 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
@Override
protected int computeMinScrollX() {
if (mIsRtl && mDisallowScrollToClearAll) {
// We aren't showing the clear all button, so use the leftmost task as the min scroll.
return getScrollForPage(getTaskViewCount() - 1);
if (getTaskViewCount() > 0) {
if (mDisallowScrollToClearAll) {
// We aren't showing the clear all button,
// so use the leftmost task as the min scroll.
if (mIsRtl) {
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
}
return getScrollForPage(mTaskViewStartIndex);
}
if (mIsRtl) {
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
}
return getScrollForPage(mTaskViewStartIndex);
}
return super.computeMinScrollX();
}
@Override
protected int computeMaxScrollX() {
if (!mIsRtl && mDisallowScrollToClearAll) {
// We aren't showing the clear all button, so use the rightmost task as the max scroll.
return getScrollForPage(getTaskViewCount() - 1);
if (getTaskViewCount() > 0) {
if (mDisallowScrollToClearAll) {
// We aren't showing the clear all button,
// so use the rightmost task as the min scroll.
if (mIsRtl) {
return getScrollForPage(mTaskViewStartIndex);
}
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
}
if (mIsRtl) {
return getScrollForPage(mTaskViewStartIndex);
}
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
}
return super.computeMaxScrollX();
}
@@ -1733,7 +1795,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
int taskCount = getTaskViewCount();
for (int i = 0; i < taskCount; i++) {
((TaskView) getChildAt(i)).setOverlayEnabled(i == overlayEnabledPage);
getTaskViewAt(i).setOverlayEnabled(i == overlayEnabledPage);
}
}