diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index bedaefa5d6..d65c59e067 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -76,8 +76,8 @@ public abstract class BaseRecentsViewStateController SCRIM_PROGRESS.set(scrim, state.getOverviewScrimAlpha(mLauncher)); SCRIM_MULTIPLIER.set(scrim, 1f); getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness()); - RECENTS_GRID_PROGRESS.set(mRecentsView, state.displayOverviewTasksAsGrid(mLauncher) - ? 1f : 0f); + RECENTS_GRID_PROGRESS.set(mRecentsView, + state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f); } @Override @@ -128,7 +128,7 @@ public abstract class BaseRecentsViewStateController toState.getOverviewModalness(), config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR)); setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, - toState.displayOverviewTasksAsGrid(mLauncher) ? 1f : 0f, LINEAR); + toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f, LINEAR); } abstract FloatProperty getTaskModalnessProperty(); diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 2ad718b63f..fb58bf6422 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -20,6 +20,7 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKG import android.content.Context; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.quickstep.util.LayoutUtils; @@ -76,7 +77,7 @@ public class BackgroundAppState extends OverviewState { } @Override - public boolean displayOverviewTasksAsGrid(Launcher launcher) { + public boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) { return false; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 372784a2c0..5a28cfdc0e 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -123,7 +123,7 @@ public class OverviewState extends LauncherState { @Override public int getVisibleElements(Launcher launcher) { - return displayOverviewTasksAsGrid(launcher) ? CLEAR_ALL_BUTTON + return displayOverviewTasksAsGrid(launcher.getDeviceProfile()) ? CLEAR_ALL_BUTTON : CLEAR_ALL_BUTTON | OVERVIEW_ACTIONS; } @@ -133,8 +133,8 @@ public class OverviewState extends LauncherState { } @Override - public boolean displayOverviewTasksAsGrid(Launcher launcher) { - return launcher.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get(); + public boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) { + return deviceProfile.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get(); } @Override diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 7df86b99c7..a2f15f5ff3 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -80,9 +80,9 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; +import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.tracing.InputConsumerProto; import com.android.launcher3.tracing.SwipeHandlerProto; @@ -124,14 +124,15 @@ import java.util.function.Consumer; * Handles the navigation gestures when Launcher is the default home activity. */ @TargetApi(Build.VERSION_CODES.R) -public abstract class AbsSwipeUpHandler, Q extends RecentsView> +public abstract class AbsSwipeUpHandler, + Q extends RecentsView, S extends BaseState> extends SwipeUpAnimationLogic implements OnApplyWindowInsetsListener, RecentsAnimationCallbacks.RecentsAnimationListener { private static final String TAG = "AbsSwipeUpHandler"; private static final String[] STATE_NAMES = DEBUG_STATES ? new String[17] : null; - protected final BaseActivityInterface mActivityInterface; + protected final BaseActivityInterface mActivityInterface; protected final InputConsumerProxy mInputConsumerProxy; protected final ActivityInitListener mActivityInitListener; // Callbacks to be made once the recents animation starts @@ -934,9 +935,15 @@ public abstract class AbsSwipeUpHandler, Q extends duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration); } } - Interpolator interpolator = - endTarget == RECENTS ? (mDp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get() - ? ACCEL_DEACCEL : OVERSHOOT_1_2) : DEACCEL; + Interpolator interpolator; + S state = mActivityInterface.stateFromGestureEndTarget(endTarget); + if (state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) { + interpolator = ACCEL_DEACCEL; + } else if (endTarget == RECENTS) { + interpolator = OVERSHOOT_1_2; + } else { + interpolator = DEACCEL; + } if (endTarget.isLauncher) { mInputConsumerProxy.enable(); @@ -1126,8 +1133,9 @@ public abstract class AbsSwipeUpHandler, Q extends } }); animatorSet.play(windowAnim); - if (mRecentsView != null && mDp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get() - && mGestureState.getEndTarget() == RECENTS) { + S state = mActivityInterface.stateFromGestureEndTarget(mGestureState.getEndTarget()); + if (mRecentsView != null && state.displayOverviewTasksAsGrid( + mActivity.getDeviceProfile())) { animatorSet.play(ObjectAnimator.ofFloat(mRecentsView, RECENTS_GRID_PROGRESS, 1)); animatorSet.play(mTaskViewSimulator.gridProgress.animateToValue(0, 1)); } @@ -1756,7 +1764,7 @@ public abstract class AbsSwipeUpHandler, Q extends public interface Factory { - AbsSwipeUpHandler, RecentsView> newHandler( + AbsSwipeUpHandler newHandler( GestureState gestureState, long touchTimeMs, boolean continuingLastGesture); } } diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 7c1d9fadbb..5942b3aaf4 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -306,6 +306,11 @@ public abstract class BaseActivityInterface callback) { + notifyRecentsOfOrientation(deviceState.getRotationTouchHelper()); DefaultAnimationFactory factory = new DefaultAnimationFactory(callback); factory.initUI(); return factory; @@ -154,4 +156,25 @@ public final class FallbackActivityInterface extends } activity.getOverviewPanel().startHome(); } + + @Override + public RecentsState stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget) { + switch (endTarget) { + case RECENTS: + return DEFAULT; + case NEW_TASK: + case LAST_TASK: + return BACKGROUND_APP; + case HOME: + default: + return HOME; + } + } + + private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) { + // reset layout on swipe to home + RecentsView recentsView = getCreatedActivity().getOverviewPanel(); + recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(), + rotationTouchHelper.getDisplayRotation()); + } } diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java index a80c111d69..7e4a352d93 100644 --- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java @@ -55,6 +55,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.SpringAnimationBuilder; import com.android.quickstep.fallback.FallbackRecentsView; +import com.android.quickstep.fallback.RecentsState; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.TransformParams; import com.android.quickstep.util.TransformParams.BuilderProxy; @@ -73,7 +74,7 @@ import java.util.function.Consumer; */ @TargetApi(Build.VERSION_CODES.R) public class FallbackSwipeHandler extends - AbsSwipeUpHandler { + AbsSwipeUpHandler { /** * Message used for receiving gesture nav contract information. We use a static messenger to diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 8d67ee697a..ebdc1e6454 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -25,6 +25,7 @@ import android.app.ActivityManager; import android.content.Intent; import android.os.Build; +import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.tracing.GestureStateProto; import com.android.launcher3.tracing.SwipeHandlerProto; @@ -213,7 +214,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL /** * @return the interface to the activity handing the UI updates for this gesture. */ - public > BaseActivityInterface getActivityInterface() { + public , + T extends StatefulActivity> BaseActivityInterface getActivityInterface() { return mActivityInterface; } diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 7efbfb8503..ca5765e469 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -18,6 +18,7 @@ package com.android.quickstep; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.LauncherState.QUICK_SWITCH; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING; @@ -270,7 +271,7 @@ public final class LauncherActivityInterface extends if (taskbarController == null) { return; } - LauncherState toState = endTarget == GestureEndTarget.RECENTS ? OVERVIEW : NORMAL; + LauncherState toState = stateFromGestureEndTarget(endTarget); taskbarController.createAnimToLauncher(toState, duration).start(); } @@ -301,4 +302,18 @@ public final class LauncherActivityInterface extends } return taskbarController.isDraggingItem(); } + + @Override + public LauncherState stateFromGestureEndTarget(GestureEndTarget endTarget) { + switch (endTarget) { + case RECENTS: + return OVERVIEW; + case NEW_TASK: + case LAST_TASK: + return QUICK_SWITCH; + case HOME: + default: + return NORMAL; + } + } } diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java index 842fb84ff9..1ce420178f 100644 --- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java @@ -27,6 +27,7 @@ import android.view.View; import androidx.annotation.NonNull; import com.android.launcher3.BaseQuickstepLauncher; +import com.android.launcher3.LauncherState; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.util.RectFSpringAnim; @@ -39,7 +40,7 @@ import com.android.systemui.shared.system.InputConsumerController; * Temporary class to allow easier refactoring */ public class LauncherSwipeHandlerV2 extends - AbsSwipeUpHandler { + AbsSwipeUpHandler { public LauncherSwipeHandlerV2(Context context, RecentsAnimationDeviceState deviceState, TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs, diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 24a761066a..54f6ce6dc6 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -25,6 +25,7 @@ import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVER import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW; import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; +import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.TASK_MODALNESS; import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; @@ -77,11 +78,12 @@ public class FallbackRecentsStateController implements StateHandler @Override public void startHome() { mActivity.startHome(); + mActivity.getStateManager().goToState(RecentsState.HOME); } /** @@ -154,6 +155,11 @@ public class FallbackRecentsView extends RecentsView super.setRunningTaskHidden(isHidden); } + @Override + protected boolean isHomeTask(TaskView taskView) { + return mHomeTaskInfo != null && taskView.hasTaskId(mHomeTaskInfo.taskId); + } + @Override public void setModalStateEnabled(boolean isModalState) { super.setModalStateEnabled(isModalState); @@ -169,6 +175,8 @@ public class FallbackRecentsView extends RecentsView @Override public void onStateTransitionStart(RecentsState toState) { setOverviewStateEnabled(true); + setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())); + setOverviewFullscreenEnabled(toState.isFullScreen()); setFreezeViewVisibility(true); } @@ -183,7 +191,7 @@ public class FallbackRecentsView extends RecentsView super.setOverviewStateEnabled(enabled); if (enabled) { RecentsState state = mActivity.getStateManager().getState(); - setDisallowScrollToClearAll(!state.hasButtons()); + setDisallowScrollToClearAll(!state.hasClearAllButton()); } } } diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java index f15a9de6f8..a9856d2dd8 100644 --- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java +++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java @@ -20,6 +20,8 @@ import static com.android.launcher3.uioverrides.states.OverviewModalTaskState.ge import android.content.Context; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statemanager.BaseState; import com.android.quickstep.RecentsActivity; @@ -29,14 +31,19 @@ import com.android.quickstep.RecentsActivity; public class RecentsState implements BaseState { private static final int FLAG_MODAL = BaseState.getFlag(0); - private static final int FLAG_HAS_BUTTONS = BaseState.getFlag(1); + private static final int FLAG_CLEAR_ALL_BUTTON = BaseState.getFlag(1); private static final int FLAG_FULL_SCREEN = BaseState.getFlag(2); + private static final int FLAG_OVERVIEW_ACTIONS = BaseState.getFlag(3); + private static final int FLAG_SHOW_AS_GRID = BaseState.getFlag(4); - public static final RecentsState DEFAULT = new RecentsState(0, FLAG_HAS_BUTTONS); + public static final RecentsState DEFAULT = new RecentsState(0, + FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID); public static final RecentsState MODAL_TASK = new ModalState(1, - FLAG_DISABLE_RESTORE | FLAG_HAS_BUTTONS | FLAG_MODAL); + FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_MODAL + | FLAG_SHOW_AS_GRID); public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2, FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN); + public static final RecentsState HOME = new RecentsState(3, 0); public final int ordinal; private final int mFlags; @@ -82,14 +89,35 @@ public class RecentsState implements BaseState { return hasFlag(FLAG_FULL_SCREEN); } - public boolean hasButtons() { - return hasFlag(FLAG_HAS_BUTTONS); + /** + * For this state, whether clear all button should be shown. + */ + public boolean hasClearAllButton() { + return hasFlag(FLAG_CLEAR_ALL_BUTTON); + } + + /** + * For this state, whether overview actions should be shown. + */ + public boolean hasOverviewActions(RecentsActivity activity) { + return hasFlag(FLAG_OVERVIEW_ACTIONS) && !showAsGrid(activity.getDeviceProfile()); } public float[] getOverviewScaleAndOffset(RecentsActivity activity) { return new float[] { NO_SCALE, NO_OFFSET }; } + /** + * For this state, whether tasks should layout as a grid rather than a list. + */ + public boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) { + return hasFlag(FLAG_SHOW_AS_GRID) && showAsGrid(deviceProfile); + } + + private boolean showAsGrid(DeviceProfile deviceProfile) { + return deviceProfile.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get(); + } + private static class ModalState extends RecentsState { public ModalState(int id, int flags) { diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java index cee33639b3..fa9e0ec1ab 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java @@ -24,6 +24,7 @@ import android.view.MotionEvent; import androidx.annotation.Nullable; import com.android.launcher3.Utilities; +import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.TestProtocol; @@ -38,7 +39,7 @@ import com.android.systemui.shared.system.InputMonitorCompat; /** * Input consumer for handling touch on the recents/Launcher activity. */ -public class OverviewInputConsumer> +public class OverviewInputConsumer, T extends StatefulActivity> implements InputConsumer { private final T mActivity; diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java index 9d31190eb6..da24b594b4 100644 --- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java @@ -150,6 +150,8 @@ public class LauncherRecentsView extends RecentsView @Override public void onStateTransitionStart(LauncherState toState) { setOverviewStateEnabled(toState.overviewUi); + setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())); + setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1); setFreezeViewVisibility(true); } @@ -160,8 +162,6 @@ public class LauncherRecentsView extends RecentsView reset(); } setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK); - setOverviewGridEnabled(finalState.displayOverviewTasksAsGrid(mActivity)); - setOverviewFullscreenEnabled(finalState.getOverviewFullscreenProgress() == 1); setFreezeViewVisibility(false); } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index f5b62d5828..8f35ea6e65 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -337,7 +337,9 @@ public abstract class RecentsView extends PagedView private float mTaskViewsPrimaryTranslation = 0; // Progress from 0 to 1 where 0 is a carousel and 1 is a 2 row grid. private float mGridProgress = 0; - private boolean mShowAsGrid; + + // The GestureEndTarget that is still in progress. + private GestureState.GestureEndTarget mCurrentGestureEndTarget; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. @@ -554,11 +556,6 @@ public abstract class RecentsView extends PagedView mLiveTileTaskViewSimulator.recentsViewScale.value = 1; mLiveTileTaskViewSimulator.setOrientationState(mOrientationState); mLiveTileTaskViewSimulator.setDrawsBelowRecents(true); - - mShowAsGrid = - mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get(); - mActivity.addOnDeviceProfileChangeListener(newDp -> - mShowAsGrid = newDp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()); } public OverScroller getScroller() { @@ -731,7 +728,7 @@ public abstract class RecentsView extends PagedView } public boolean isTaskViewVisible(TaskView tv) { - if (mShowAsGrid) { + if (showAsGrid()) { int screenStart = mOrientationHandler.getPrimaryScroll(this); int screenEnd = screenStart + mOrientationHandler.getMeasuredSize(this); return isTaskViewWithinBounds(tv, screenStart, screenEnd); @@ -743,9 +740,9 @@ public abstract class RecentsView extends PagedView private boolean isTaskViewWithinBounds(TaskView tv, int start, int end) { int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment( - mOverviewFullscreenEnabled, mOverviewGridEnabled); + mOverviewFullscreenEnabled, showAsGrid()); int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment( - mOverviewFullscreenEnabled, mOverviewGridEnabled)); + mOverviewFullscreenEnabled, showAsGrid())); int taskEnd = taskStart + taskSize; return (taskStart >= start && taskStart <= end) || (taskEnd >= start && taskEnd <= end); @@ -813,7 +810,7 @@ public abstract class RecentsView extends PagedView public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); - if (mShowAsGrid) { + if (showAsGrid()) { int taskCount = getTaskViewCount(); for (int i = 0; i < taskCount; i++) { TaskView taskView = getTaskViewAt(i); @@ -880,7 +877,7 @@ public abstract class RecentsView extends PagedView @Override protected boolean snapToPageInFreeScroll() { - return !mShowAsGrid; + return !showAsGrid(); } @Override @@ -1091,14 +1088,35 @@ public abstract class RecentsView extends PagedView * Updates TaskView scaling and translation required to support variable width. */ private void updateTaskSize() { - float accumulatedTranslationX = 0; final int taskCount = getTaskViewCount(); + float accumulatedTranslationX = 0; + float[] fullscreenTranslations = new float[taskCount]; + int firstNonHomeTaskIndex = 0; for (int i = 0; i < taskCount; i++) { TaskView taskView = getTaskViewAt(i); + if (isHomeTask(taskView)) { + if (firstNonHomeTaskIndex == i) { + firstNonHomeTaskIndex++; + } + continue; + } + taskView.updateTaskSize(); - taskView.setAccumulatedFullscreenTranslationX(accumulatedTranslationX); - accumulatedTranslationX += taskView.getFullscreenTranslationX(); + fullscreenTranslations[i] += accumulatedTranslationX; + float widthDiff = + taskView.getLayoutParams().width * (1 - taskView.getFullscreenScale()); + float fullscreenTranslationX = mIsRtl ? widthDiff : -widthDiff; + fullscreenTranslations[i] += fullscreenTranslationX; + accumulatedTranslationX += fullscreenTranslationX; } + + // We need to maintain first non-home task's full screen translation at 0, now shift + // translation of all the TaskViews to achieve that. + for (int i = firstNonHomeTaskIndex; i < taskCount; i++) { + getTaskViewAt(i).setFullscreenTranslationX( + fullscreenTranslations[i] - fullscreenTranslations[firstNonHomeTaskIndex]); + } + updateGridProperties(); } @@ -1204,7 +1222,7 @@ public abstract class RecentsView extends PagedView int upper = 0; int visibleStart = 0; int visibleEnd = 0; - if (mShowAsGrid) { + if (showAsGrid()) { int screenStart = mOrientationHandler.getPrimaryScroll(this); int pageOrientedSize = mOrientationHandler.getMeasuredSize(this); int halfScreenSize = pageOrientedSize / 2; @@ -1224,7 +1242,7 @@ public abstract class RecentsView extends PagedView Task task = taskView.getTask(); int index = indexOfChild(taskView); boolean visible; - if (mShowAsGrid) { + if (showAsGrid()) { visible = isTaskViewWithinBounds(taskView, visibleStart, visibleEnd); } else { visible = lower <= index && index <= upper; @@ -1404,7 +1422,7 @@ public abstract class RecentsView extends PagedView * Called when a gesture from an app has finished, and an end target has been determined. */ public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) { - + mCurrentGestureEndTarget = endTarget; } /** @@ -1425,9 +1443,11 @@ public abstract class RecentsView extends PagedView animateUpRunningTaskIconScale(); // TODO: This should be tied to whether there is a focus app on overview. - if (!mShowAsGrid) { + if (!showAsGrid()) { animateActionsViewIn(); } + + mCurrentGestureEndTarget = null; } /** @@ -1601,11 +1621,19 @@ public abstract class RecentsView extends PagedView float topAccumulatedTranslationX = 0; float bottomAccumulatedTranslationX = 0; IntSet topSet = new IntSet(); + IntSet bottomSet = new IntSet(); float[] gridTranslations = new float[taskCount]; + int firstNonHomeTaskIndex = 0; for (int i = 0; i < taskCount; i++) { TaskView taskView = getTaskViewAt(i); + if (isHomeTask(taskView)) { + if (firstNonHomeTaskIndex == i) { + firstNonHomeTaskIndex++; + } + continue; + } + taskView.setGridScale(gridScale); - gridTranslations[i] = 0; float scaledWidth = taskView.getLayoutParams().width * gridScale; float taskGridHorizontalDiff; @@ -1639,7 +1667,7 @@ public abstract class RecentsView extends PagedView // Move horizontally into empty space. float widthOffset = 0; - for (int j = i - 1; !topSet.contains(j) && j >= 0; j--) { + for (int j = i - 1; bottomSet.contains(j); j--) { widthOffset += getTaskViewAt(j).getLayoutParams().width * gridScale + mPageSpacing; } @@ -1650,6 +1678,7 @@ public abstract class RecentsView extends PagedView } else { gridTranslations[i] += bottomAccumulatedTranslationX; bottomRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing; + bottomSet.add(i); // Move into bottom row. float heightOffset = (boxLength + mTaskTopMargin) * gridScale + mRowSpacing; @@ -1704,31 +1733,33 @@ public abstract class RecentsView extends PagedView clearAllAccumulatedTranslation + clearAllShorterRowCompensation + clearAllShortTotalCompensation; - // We need to maintain first task's grid translation at 0, now shift translation of all - // the TaskViews to achieve that. - for (int i = 0; i < taskCount; i++) { - getTaskViewAt(i).setGridTranslationX(gridTranslations[i] - gridTranslations[0]); + // We need to maintain first non-home task's grid translation at 0, now shift translation + // of all the TaskViews to achieve that. + for (int i = firstNonHomeTaskIndex; i < taskCount; i++) { + getTaskViewAt(i).setGridTranslationX( + gridTranslations[i] - gridTranslations[firstNonHomeTaskIndex]); } - mClearAllButton.setGridTranslationPrimary(clearAllTotalTranslationX - gridTranslations[0]); + mClearAllButton.setGridTranslationPrimary( + clearAllTotalTranslationX - gridTranslations[firstNonHomeTaskIndex]); setGridProgress(mGridProgress); } + protected boolean isHomeTask(TaskView taskView) { + return false; + } + /** * Moves TaskView and ClearAllButton between carousel and 2 row grid. * * @param gridProgress 0 = carousel; 1 = 2 row grid. */ - public void setGridProgress(float gridProgress) { + private void setGridProgress(float gridProgress) { int taskCount = getTaskViewCount(); if (taskCount == 0) { return; } - if (!mShowAsGrid) { - gridProgress = 0; - } - mGridProgress = gridProgress; for (int i = 0; i < taskCount; i++) { @@ -1872,7 +1903,8 @@ public abstract class RecentsView extends PagedView if (animateTaskView) { addDismissedTaskAnimations(taskView, duration, anim); } - } else if (!mShowAsGrid) { // Don't animate other tasks when dismissing in grid for now + } else if (!showAsGrid()) { + // For grid layout, don't animate other tasks when dismissing in grid for now. // If we just take newScroll - oldScroll, everything to the right of dragged task // translates to the left. We need to offset this in some cases: // - In RTL, add page offset to all pages, since we want pages to move to the right @@ -2865,9 +2897,9 @@ public abstract class RecentsView extends PagedView float scrollDiff = 0; if (child instanceof TaskView) { scrollDiff = ((TaskView) child).getScrollAdjustment(mOverviewFullscreenEnabled, - mOverviewGridEnabled); + showAsGrid()); } else if (child instanceof ClearAllButton) { - scrollDiff = ((ClearAllButton) child).getScrollAdjustment(mOverviewGridEnabled); + scrollDiff = ((ClearAllButton) child).getScrollAdjustment(showAsGrid()); } if (scrollDiff != 0) { @@ -2884,9 +2916,9 @@ public abstract class RecentsView extends PagedView View child = getChildAt(index); if (child instanceof TaskView) { childOffset += ((TaskView) child).getOffsetAdjustment(mOverviewFullscreenEnabled, - mOverviewGridEnabled); + showAsGrid()); } else if (child instanceof ClearAllButton) { - childOffset += ((ClearAllButton) child).getOffsetAdjustment(mOverviewGridEnabled); + childOffset += ((ClearAllButton) child).getOffsetAdjustment(showAsGrid()); } return childOffset; } @@ -2898,7 +2930,7 @@ public abstract class RecentsView extends PagedView return super.getChildVisibleSize(index); } return (int) (super.getChildVisibleSize(index) * taskView.getSizeAdjustment( - mOverviewFullscreenEnabled, mOverviewGridEnabled)); + mOverviewFullscreenEnabled, showAsGrid())); } @Override @@ -3109,6 +3141,12 @@ public abstract class RecentsView extends PagedView return mSizeStrategy; } + private boolean showAsGrid() { + return mOverviewGridEnabled || (mCurrentGestureEndTarget != null + && mSizeStrategy.stateFromGestureEndTarget( + mCurrentGestureEndTarget).displayOverviewTasksAsGrid(mActivity.getDeviceProfile())); + } + /** * Used to register callbacks for when our empty message state changes. * diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index cd8ea7675f..809adcbe21 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -27,8 +27,8 @@ import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.widget.Toast.LENGTH_SHORT; -import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; +import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION; import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; @@ -275,7 +275,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private float mTaskResistanceTranslationY; // The following translation variables should only be used in the same orientation as Launcher. private float mFullscreenTranslationX; - private float mAccumulatedFullscreenTranslationX; private float mBoxTranslationY; // The following grid translations scales with mGridProgress. private float mGridTranslationX; @@ -750,9 +749,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { @Override public void onRecycle() { - mFullscreenTranslationX = mAccumulatedFullscreenTranslationX = mGridTranslationX = - mGridTranslationY = - mGridOffsetTranslationX = mBoxTranslationY = mNonRtlVisibleOffset = 0f; + mFullscreenTranslationX = mGridTranslationX = mGridTranslationY = + mGridOffsetTranslationX = mBoxTranslationY = mNonRtlVisibleOffset = 0f; resetViewTransforms(); // Clear any references to the thumbnail (it will be re-read either from the cache or the // system on next bind) @@ -864,6 +862,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { applyScale(); } + public float getFullscreenScale() { + return mFullscreenScale; + } + public void setGridScale(float gridScale) { mGridScale = gridScale; applyScale(); @@ -921,20 +923,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { applyTranslationY(); } - private void setFullscreenTranslationX(float fullscreenTranslationX) { + public void setFullscreenTranslationX(float fullscreenTranslationX) { mFullscreenTranslationX = fullscreenTranslationX; applyTranslationX(); } - public float getFullscreenTranslationX() { - return mFullscreenTranslationX; - } - - public void setAccumulatedFullscreenTranslationX(float accumulatedFullscreenTranslationX) { - mAccumulatedFullscreenTranslationX = accumulatedFullscreenTranslationX; - applyTranslationX(); - } - public void setGridTranslationX(float gridTranslationX) { mGridTranslationX = gridTranslationX; applyTranslationX(); @@ -965,7 +958,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { float scrollAdjustment = 0; if (fullscreenEnabled) { - scrollAdjustment += mFullscreenTranslationX + mAccumulatedFullscreenTranslationX; + scrollAdjustment += mFullscreenTranslationX; } if (gridEnabled) { scrollAdjustment += mGridTranslationX; @@ -999,7 +992,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private void applyTranslationX() { setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX - + getFullscreenTrans(mFullscreenTranslationX + mAccumulatedFullscreenTranslationX) + + getFullscreenTrans(mFullscreenTranslationX) + getGridTrans(mGridTranslationX + mGridOffsetTranslationX)); } @@ -1243,10 +1236,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } setFullscreenScale(fullscreenScale); - float widthDiff = params.width * (1 - mFullscreenScale); - setFullscreenTranslationX( - getLayoutDirection() == LAYOUT_DIRECTION_RTL ? -widthDiff : widthDiff); - if (params.width != expectedWidth || params.height != expectedHeight) { params.width = expectedWidth; params.height = expectedHeight; @@ -1254,7 +1243,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } } else { setBoxTranslationY(0); - setFullscreenTranslationX(0); setFullscreenScale(1); if (params.width != ViewGroup.LayoutParams.MATCH_PARENT) { params.width = ViewGroup.LayoutParams.MATCH_PARENT; diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index aa97450a2b..ae75b51799 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -237,13 +237,6 @@ public abstract class LauncherState implements BaseState { return 0; } - /** - * For this state, whether tasks should layout as a grid rather than a list. - */ - public boolean displayOverviewTasksAsGrid(Launcher launcher) { - return false; - } - /** * For this state, how much additional vertical translation there should be for each of the * child TaskViews. diff --git a/src/com/android/launcher3/statemanager/BaseState.java b/src/com/android/launcher3/statemanager/BaseState.java index daec1d8508..122573cfa1 100644 --- a/src/com/android/launcher3/statemanager/BaseState.java +++ b/src/com/android/launcher3/statemanager/BaseState.java @@ -17,6 +17,8 @@ package com.android.launcher3.statemanager; import android.content.Context; +import com.android.launcher3.DeviceProfile; + /** * Interface representing a state of a StatefulActivity */ @@ -52,4 +54,11 @@ public interface BaseState { * Returns if the state has the provided flag */ boolean hasFlag(int flagMask); + + /** + * For this state, whether tasks should layout as a grid rather than a list. + */ + default boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) { + return false; + } }