Show overview as grid in fallback recents
- Replace mShowAsGrid with state specific mOverviewGridEnabled and mCurrentGestureEndTarget
- Avoid showing invisible home task in grid
- Fix quick switch out of orientation in fallback recents
- Add a HOME state to switch to when starting home, to avoid showing grid overview briefly in quick switch
- Separate clear all button and overview actions handling
- Always maintain first task's fullscreen translation at 0 to avoid jumping when mOverviewFullscreenEnabled changes
- Moved fullscreenTranslation calculation to RecentsView
- Added GestureEndTarget -> BaseState translation to allow querying displayOverviewAsGrid for a displayOverviewTasksAsGrid
Bug: 174464863
Test: Launch overveiw from home, launch overveiw from app, launch into app, test for both small and large screens
Change-Id: Iee06d94d3067ea45cadd2051717223ddc0e6e70c
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index bedaefa..d65c59e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -76,8 +76,8 @@
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 @@
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 2ad718b..fb58bf6 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 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 @@
}
@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 372784a..5a28cfd 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 @@
@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 @@
}
@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 7df86b9..a2f15f5 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.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 @@
* Handles the navigation gestures when Launcher is the default home activity.
*/
@TargetApi(Build.VERSION_CODES.R)
-public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends RecentsView>
+public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
+ Q extends RecentsView, S extends BaseState<S>>
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<?, T> mActivityInterface;
+ protected final BaseActivityInterface<S, T> mActivityInterface;
protected final InputConsumerProxy mInputConsumerProxy;
protected final ActivityInitListener mActivityInitListener;
// Callbacks to be made once the recents animation starts
@@ -934,9 +935,15 @@
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 @@
}
});
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 interface Factory {
- AbsSwipeUpHandler<StatefulActivity<?>, 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 7c1d9fa..5942b3a 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -306,6 +306,11 @@
public void onSystemUiFlagsChanged(int systemUiStateFlags) {
}
+ /**
+ * Returns the expected STATE_TYPE from the provided GestureEndTarget.
+ */
+ public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
+
public interface AnimationFactory {
void createActivityInterface(long transitionLength);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index db290d6..bffe3a1 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -18,6 +18,7 @@
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
+import static com.android.quickstep.fallback.RecentsState.HOME;
import android.content.Context;
import android.graphics.Rect;
@@ -81,6 +82,7 @@
@Override
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
+ notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
factory.initUI();
return factory;
@@ -154,4 +156,25 @@
}
activity.<RecentsView>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 a80c111..7e4a352 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.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 @@
*/
@TargetApi(Build.VERSION_CODES.R)
public class FallbackSwipeHandler extends
- AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView> {
+ AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView, RecentsState> {
/**
* 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 8d67ee6..ebdc1e6 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -25,6 +25,7 @@
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 @@
/**
* @return the interface to the activity handing the UI updates for this gesture.
*/
- public <T extends StatefulActivity<?>> BaseActivityInterface<?, T> getActivityInterface() {
+ public <S extends BaseState<S>,
+ T extends StatefulActivity<S>> BaseActivityInterface<S, T> getActivityInterface() {
return mActivityInterface;
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 7efbfb8..ca5765e 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -18,6 +18,7 @@
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 @@
if (taskbarController == null) {
return;
}
- LauncherState toState = endTarget == GestureEndTarget.RECENTS ? OVERVIEW : NORMAL;
+ LauncherState toState = stateFromGestureEndTarget(endTarget);
taskbarController.createAnimToLauncher(toState, duration).start();
}
@@ -301,4 +302,18 @@
}
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 842fb84..1ce4201 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -27,6 +27,7 @@
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 @@
* Temporary class to allow easier refactoring
*/
public class LauncherSwipeHandlerV2 extends
- AbsSwipeUpHandler<BaseQuickstepLauncher, RecentsView> {
+ AbsSwipeUpHandler<BaseQuickstepLauncher, RecentsView, LauncherState> {
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 24a7610..54f6ce6 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.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 @@
private void setProperties(RecentsState state, StateAnimationConfig config,
PropertySetter setter) {
- float buttonAlpha = state.hasButtons() ? 1 : 0;
+ float clearAllButtonAlpha = state.hasClearAllButton() ? 1 : 0;
setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
- buttonAlpha, LINEAR);
+ clearAllButtonAlpha, LINEAR);
+ float overviewButtonAlpha = state.hasOverviewActions(mActivity) ? 1 : 0;
setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
- MultiValueAlpha.VALUE, buttonAlpha, LINEAR);
+ MultiValueAlpha.VALUE, overviewButtonAlpha, LINEAR);
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
@@ -94,5 +96,7 @@
setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
setter.setFloat(mRecentsView, FULLSCREEN_PROGRESS, state.isFullScreen() ? 1 : 0, LINEAR);
+ setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS,
+ state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()) ? 1f : 0f, LINEAR);
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 02fd5bb..e075045 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -66,6 +66,7 @@
@Override
public void startHome() {
mActivity.startHome();
+ mActivity.getStateManager().goToState(RecentsState.HOME);
}
/**
@@ -155,6 +156,11 @@
}
@Override
+ protected boolean isHomeTask(TaskView taskView) {
+ return mHomeTaskInfo != null && taskView.hasTaskId(mHomeTaskInfo.taskId);
+ }
+
+ @Override
public void setModalStateEnabled(boolean isModalState) {
super.setModalStateEnabled(isModalState);
if (isModalState) {
@@ -169,6 +175,8 @@
@Override
public void onStateTransitionStart(RecentsState toState) {
setOverviewStateEnabled(true);
+ setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
+ setOverviewFullscreenEnabled(toState.isFullScreen());
setFreezeViewVisibility(true);
}
@@ -183,7 +191,7 @@
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 f15a9de..a9856d2 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -20,6 +20,8 @@
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 @@
public class RecentsState implements BaseState<RecentsState> {
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 @@
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 cee3363..fa9e0ec 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -24,6 +24,7 @@
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 @@
/**
* Input consumer for handling touch on the recents/Launcher activity.
*/
-public class OverviewInputConsumer<T extends StatefulActivity<?>>
+public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulActivity<S>>
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 9d31190..da24b59 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -150,6 +150,8 @@
@Override
public void onStateTransitionStart(LauncherState toState) {
setOverviewStateEnabled(toState.overviewUi);
+ setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
+ setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
setFreezeViewVisibility(true);
}
@@ -160,8 +162,6 @@
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 f5b62d5..8f35ea6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -337,7 +337,9 @@
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 @@
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 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 @@
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 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 @@
@Override
protected boolean snapToPageInFreeScroll() {
- return !mShowAsGrid;
+ return !showAsGrid();
}
@Override
@@ -1091,14 +1088,35 @@
* 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 @@
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 @@
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 @@
* 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 @@
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 @@
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 @@
// 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 @@
} 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 @@
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 @@
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 @@
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 @@
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 @@
return super.getChildVisibleSize(index);
}
return (int) (super.getChildVisibleSize(index) * taskView.getSizeAdjustment(
- mOverviewFullscreenEnabled, mOverviewGridEnabled));
+ mOverviewFullscreenEnabled, showAsGrid()));
}
@Override
@@ -3109,6 +3141,12 @@
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 cd8ea76..809adcb 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_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 @@
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 @@
@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 @@
applyScale();
}
+ public float getFullscreenScale() {
+ return mFullscreenScale;
+ }
+
public void setGridScale(float gridScale) {
mGridScale = gridScale;
applyScale();
@@ -921,20 +923,11 @@
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 float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
float scrollAdjustment = 0;
if (fullscreenEnabled) {
- scrollAdjustment += mFullscreenTranslationX + mAccumulatedFullscreenTranslationX;
+ scrollAdjustment += mFullscreenTranslationX;
}
if (gridEnabled) {
scrollAdjustment += mGridTranslationX;
@@ -999,7 +992,7 @@
private void applyTranslationX() {
setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX
- + getFullscreenTrans(mFullscreenTranslationX + mAccumulatedFullscreenTranslationX)
+ + getFullscreenTrans(mFullscreenTranslationX)
+ getGridTrans(mGridTranslationX + mGridOffsetTranslationX));
}
@@ -1243,10 +1236,6 @@
}
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 @@
}
} 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 aa97450..ae75b51 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -238,13 +238,6 @@
}
/**
- * 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 daec1d8..122573c 100644
--- a/src/com/android/launcher3/statemanager/BaseState.java
+++ b/src/com/android/launcher3/statemanager/BaseState.java
@@ -17,6 +17,8 @@
import android.content.Context;
+import com.android.launcher3.DeviceProfile;
+
/**
* Interface representing a state of a StatefulActivity
*/
@@ -52,4 +54,11 @@
* 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;
+ }
}