diff --git a/quickstep/recents_ui_overrides/res/drawable/chip_scrim_gradient.xml b/quickstep/recents_ui_overrides/res/drawable/chip_scrim_gradient.xml new file mode 100644 index 0000000000..5a2dfb7b4a --- /dev/null +++ b/quickstep/recents_ui_overrides/res/drawable/chip_scrim_gradient.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/quickstep/recents_ui_overrides/res/values/colors.xml b/quickstep/recents_ui_overrides/res/values/colors.xml index 361f5f70c0..f03f118f38 100644 --- a/quickstep/recents_ui_overrides/res/values/colors.xml +++ b/quickstep/recents_ui_overrides/res/values/colors.xml @@ -15,6 +15,7 @@ --> #fff + #39000000 #61000000 #61FFFFFF diff --git a/quickstep/recents_ui_overrides/res/values/dimens.xml b/quickstep/recents_ui_overrides/res/values/dimens.xml index 363840a217..9266b0652b 100644 --- a/quickstep/recents_ui_overrides/res/values/dimens.xml +++ b/quickstep/recents_ui_overrides/res/values/dimens.xml @@ -20,6 +20,7 @@ 10dp 12dp 20dp + 16dp 2dp 16dp 26dp diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 6c64bf7c75..79b4002498 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -197,15 +197,15 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti case INDEX_RECENTS_FADE_ANIM: return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(), RecentsView.CONTENT_ALPHA, values); - case INDEX_RECENTS_TRANSLATE_X_ANIM: - // TODO: Do not assume motion across X axis for adjacent page - return new SpringAnimationBuilder<>( - mLauncher.getOverviewPanel(), ADJACENT_PAGE_OFFSET) - .setMinimumVisibleChange(1f / mLauncher.getOverviewPanel().getWidth()) + case INDEX_RECENTS_TRANSLATE_X_ANIM: { + RecentsView rv = mLauncher.getOverviewPanel(); + return new SpringAnimationBuilder(mLauncher) + .setMinimumVisibleChange(1f / rv.getPageOffsetScale()) .setDampingRatio(0.8f) .setStiffness(250) .setValues(values) - .build(mLauncher); + .build(rv, ADJACENT_PAGE_OFFSET); + } case INDEX_PAUSE_TO_OVERVIEW_ANIM: { StateAnimationConfig config = new StateAnimationConfig(); config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW; diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java index 079a738036..d93aea44a7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java @@ -73,10 +73,6 @@ public class AllAppsTipView { if (!hasSeenAllAppsTip(launcher)) { launcher.getStateManager().addStateListener( new LauncherStateManager.StateListener() { - @Override - public void onStateTransitionStart(LauncherState toState) { - } - @Override public void onStateTransitionComplete(LauncherState finalState) { if (finalState == ALL_APPS) { diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java index ec46418949..81a6070664 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java @@ -250,9 +250,6 @@ public class AppsDividerView extends View implements LauncherStateManager.StateL mLauncher.getStateManager().removeStateListener(this); } - @Override - public void onStateTransitionStart(LauncherState toState) { } - @Override public void onStateTransitionComplete(LauncherState finalState) { if (finalState == ALL_APPS) { diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java index 8e55609e7d..e68627a8f6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java @@ -157,9 +157,6 @@ public class PredictionUiStateManager implements StateListener, ItemInfoUpdateRe @Override public void reapplyItemInfo(ItemInfoWithIcon info) { } - @Override - public void onStateTransitionStart(LauncherState toState) { } - @Override public void onStateTransitionComplete(LauncherState state) { if (mAppsView == null) { diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 77118d58af..2b456ecec8 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -15,7 +15,6 @@ */ package com.android.launcher3.uioverrides.touchcontrollers; -import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; @@ -23,6 +22,7 @@ import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.touch.AbstractStateChangeTouchController.SUCCESS_TRANSITION_PROGRESS; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.ValueAnimator; @@ -131,12 +131,8 @@ public class NavBarToHomeTouchController implements TouchController, final PendingAnimation builder = new PendingAnimation(accuracy); if (mStartState == OVERVIEW) { RecentsView recentsView = mLauncher.getOverviewPanel(); - float pullbackDist = mPullbackDistance; - if (!recentsView.isRtl()) { - pullbackDist = -pullbackDist; - } - - builder.setFloat(recentsView, VIEW_TRANSLATE_X, pullbackDist, PULLBACK_INTERPOLATOR); + builder.setFloat(recentsView, ADJACENT_PAGE_OFFSET, + -mPullbackDistance / recentsView.getPageOffsetScale(), PULLBACK_INTERPOLATOR); if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { builder.addOnFrameCallback( () -> recentsView.redrawLiveTile(false /* mightNeedToRefill */)); diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java index 71aa2e8d99..381ecf1c4b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java @@ -166,8 +166,8 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo float velocityDp = dpiFromPx(velocity); boolean isFling = Math.abs(velocityDp) > 1; LauncherStateManager stateManager = mLauncher.getStateManager(); - if (isFling) { - // When flinging, go back to home instead of overview. + boolean goToHomeInsteadOfOverview = isFling; + if (goToHomeInsteadOfOverview) { if (velocity > 0) { stateManager.goToState(NORMAL, true, () -> onSwipeInteractionCompleted(NORMAL, Touch.FLING)); @@ -187,20 +187,21 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo () -> onSwipeInteractionCompleted(NORMAL, Touch.SWIPE))); anim.start(); } - } else { - if (mReachedOverview) { - float distanceDp = dpiFromPx(Math.max( - Math.abs(mRecentsView.getTranslationX()), - Math.abs(mRecentsView.getTranslationY()))); - long duration = (long) Math.max(TRANSLATION_ANIM_MIN_DURATION_MS, - distanceDp / TRANSLATION_ANIM_VELOCITY_DP_PER_MS); - mRecentsView.animate() - .translationX(0) - .translationY(0) - .setInterpolator(ACCEL_DEACCEL) - .setDuration(duration) - .withEndAction(this::maybeSwipeInteractionToOverviewComplete); - } + } + if (mReachedOverview) { + float distanceDp = dpiFromPx(Math.max( + Math.abs(mRecentsView.getTranslationX()), + Math.abs(mRecentsView.getTranslationY()))); + long duration = (long) Math.max(TRANSLATION_ANIM_MIN_DURATION_MS, + distanceDp / TRANSLATION_ANIM_VELOCITY_DP_PER_MS); + mRecentsView.animate() + .translationX(0) + .translationY(0) + .setInterpolator(ACCEL_DEACCEL) + .setDuration(duration) + .withEndAction(goToHomeInsteadOfOverview + ? null + : this::maybeSwipeInteractionToOverviewComplete); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 32ab98bd4d..d22e5afcc5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -334,7 +334,7 @@ public abstract class BaseSwipeUpHandler mTaskAnimationManager = taskAnimationManager; mTouchTimeMs = touchTimeMs; mContinuingLastGesture = continuingLastGesture; - mTaskViewSimulator = new TaskViewSimulator(context, LayoutUtils::calculateLauncherTaskSize); + mTaskViewSimulator = new TaskViewSimulator( + context, LayoutUtils::calculateLauncherTaskSize, true); initAfterSubclassConstructor(); initStateCallbacks(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 9b5a935e6b..ce7a141bae 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static android.content.Intent.ACTION_CHOOSER; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; @@ -23,6 +24,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.GestureState.DEFAULT_STATE; +import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED; @@ -597,7 +599,7 @@ public class TouchInteractionService extends Service implements PluginListener { } public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); + super(context, attrs, defStyleAttr, false); } @Override @@ -195,9 +195,4 @@ public class FallbackRecentsView extends RecentsView { } super.applyLoadPlan(tasks); } - - @Override - protected boolean supportsVerticalLandscape() { - return false; - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java index 6c48bf5347..5abbd86a86 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java @@ -264,7 +264,8 @@ public class AppWindowAnimationHelper { mTmpRectF.set(mTargetRect); Utilities.scaleRectFAboutCenter(mTmpRectF, params.mOffsetScale); mCurrentRect.set(mRectFEvaluator.evaluate(params.mProgress, mSourceRect, mTmpRectF)); - if (mOrientedState == null || mOrientedState.areMultipleLayoutOrientationsDisabled()) { + if (mOrientedState == null + || !mOrientedState.isMultipleOrientationSupportedByDevice()) { mCurrentRect.offset(params.mOffset, 0); } else { int displayRotation = mOrientedState.getDisplayRotation(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index bde6f9af19..820bd1745a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -28,6 +28,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.view.View; import android.view.ViewGroup; @@ -185,13 +186,14 @@ public class StaggeredWorkspaceAnim { ResourceProvider rp = DynamicResource.provider(v.getContext()); float stiffness = rp.getFloat(R.dimen.staggered_stiffness); float damping = rp.getFloat(R.dimen.staggered_damping_ratio); - ObjectAnimator springTransY = new SpringAnimationBuilder<>(v, VIEW_TRANSLATE_Y) + ValueAnimator springTransY = new SpringAnimationBuilder(v.getContext()) .setStiffness(stiffness) .setDampingRatio(damping) .setMinimumVisibleChange(1f) + .setStartValue(mSpringTransY) .setEndValue(0) .setStartVelocity(mVelocity) - .build(v.getContext()); + .build(v, VIEW_TRANSLATE_Y); springTransY.setStartDelay(startDelay); mAnimators.play(springTransY); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java index 0131fdf5c4..9781300117 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java @@ -15,9 +15,13 @@ */ package com.android.quickstep.util; +import static android.view.Surface.ROTATION_0; + import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.launcher3.states.RotationHelper.deltaRotation; import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE; import static com.android.quickstep.util.AppWindowAnimationHelper.applySurfaceParams; +import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled; import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; @@ -33,7 +37,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsAnimationTargets; @@ -54,6 +57,7 @@ public class TaskViewSimulator { private final Rect mTmpCropRect = new Rect(); private final RectF mTempRectF = new RectF(); + private final float[] mTempPoint = new float[2]; private final RecentsOrientedState mOrientationState; private final Context mContext; @@ -91,11 +95,17 @@ public class TaskViewSimulator { private boolean mLayoutValid = false; private boolean mScrollValid = false; - public TaskViewSimulator(Context context, TaskSizeProvider sizeProvider) { + public TaskViewSimulator(Context context, TaskSizeProvider sizeProvider, + boolean rotationSupportedByActivity) { mContext = context; mSizeProvider = sizeProvider; mPositionHelper = new PreviewPositionHelper(context); - mOrientationState = new RecentsOrientedState(context); + + mOrientationState = new RecentsOrientedState(context, rotationSupportedByActivity, + i -> { }); + // We do not need to attach listeners as the simulator is created just for the gesture + // duration, and any settings are unlikely to change during this + mOrientationState.initWithoutListeners(); mCurrentFullscreenParams = new FullscreenDrawParams(context); mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); @@ -114,11 +124,15 @@ public class TaskViewSimulator { * @see com.android.quickstep.views.RecentsView#setLayoutRotation(int, int) */ public void setLayoutRotation(int touchRotation, int displayRotation) { - if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) { - return; + int launcherRotation; + if (!mOrientationState.isMultipleOrientationSupportedByDevice() + || mOrientationState.isHomeRotationAllowed()) { + launcherRotation = displayRotation; + } else { + launcherRotation = ROTATION_0; } - mOrientationState.update(touchRotation, displayRotation, - mOrientationState.getLauncherRotation()); + + mOrientationState.update(touchRotation, displayRotation, launcherRotation); mLayoutValid = false; } @@ -180,7 +194,7 @@ public class TaskViewSimulator { mLayoutValid = true; getFullScreenScale(); - mThumbnailData.rotation = FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get() + mThumbnailData.rotation = isFixedRotationTransformEnabled(mContext) ? mOrientationState.getDisplayRotation() : mPositionHelper.getCurrentRotation(); mPositionHelper.updateThumbnailMatrix(mThumbnailPosition, mThumbnailData, @@ -226,7 +240,8 @@ public class TaskViewSimulator { // Apply recensView matrix mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y); - postDisplayRotation(mOrientationState.getDisplayRotation(), + postDisplayRotation(deltaRotation( + mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()), mDp.widthPx, mDp.heightPx, mMatrix); // Crop rect is the inverse of thumbnail matrix @@ -253,7 +268,7 @@ public class TaskViewSimulator { builder.withAlpha(alpha) .withMatrix(mMatrix) .withWindowCrop(mTmpCropRect) - .withCornerRadius(mCurrentFullscreenParams.mCurrentDrawnCornerRadius); + .withCornerRadius(getCurrentCornerRadius()); } else if (params.getTargetSet().hasRecents) { // If home has a different target then recents, reverse anim the home target. builder.withAlpha(fullScreenProgress.value * params.getTargetAlpha()); @@ -270,6 +285,20 @@ public class TaskViewSimulator { applySurfaceParams(params.getSyncTransactionApplier(), surfaceParams); } + /** + * Returns the corner radius that should be applied to the target so that it matches the + * TaskView + */ + public float getCurrentCornerRadius() { + float visibleRadius = mCurrentFullscreenParams.mCurrentDrawnCornerRadius; + mTempPoint[0] = visibleRadius; + mTempPoint[1] = 0; + mInversePositionMatrix.mapVectors(mTempPoint); + + // Ideally we should use square-root. This is an optimization as one of the dimension is 0. + return Math.max(Math.abs(mTempPoint[0]), Math.abs(mTempPoint[1])); + } + /** * Interface for calculating taskSize */ diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index 454223e06f..0b6d340313 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -45,7 +45,6 @@ import com.android.launcher3.LauncherStateManager.StateListener; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; import com.android.launcher3.util.TraceHelper; @@ -96,7 +95,7 @@ public class LauncherRecentsView extends RecentsView } public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); + super(context, attrs, defStyleAttr, true); mActivity.getStateManager().addStateListener(this); } @@ -264,12 +263,6 @@ public class LauncherRecentsView extends RecentsView return mTransformParams; } - @Override - protected boolean supportsVerticalLandscape() { - return FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get() - && !mOrientationState.areMultipleLayoutOrientationsDisabled(); - } - @Override public void reset() { super.reset(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java index 93e68c0f5d..d160686f73 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java @@ -48,7 +48,8 @@ public class OverviewActionsView extends FrameLayo HIDDEN_NON_ZERO_ROTATION, HIDDEN_NO_TASKS, HIDDEN_GESTURE_RUNNING, - HIDDEN_NO_RECENTS}) + HIDDEN_NO_RECENTS, + HIDDEN_FULLESCREEN_PROGRESS}) @Retention(RetentionPolicy.SOURCE) public @interface ActionsHiddenFlags { } @@ -58,6 +59,7 @@ public class OverviewActionsView extends FrameLayo public static final int HIDDEN_NO_TASKS = 1 << 3; public static final int HIDDEN_GESTURE_RUNNING = 1 << 4; public static final int HIDDEN_NO_RECENTS = 1 << 5; + public static final int HIDDEN_FULLESCREEN_PROGRESS = 1 << 6; private static final int INDEX_CONTENT_ALPHA = 0; private static final int INDEX_VISIBILITY_ALPHA = 1; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index b687920f49..6041917f67 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -38,6 +38,7 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType. import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; +import static com.android.quickstep.views.OverviewActionsView.HIDDEN_FULLESCREEN_PROGRESS; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_GESTURE_RUNNING; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS; @@ -69,14 +70,13 @@ import android.text.StaticLayout; import android.text.TextPaint; import android.util.AttributeSet; import android.util.FloatProperty; +import android.util.Log; import android.util.Property; import android.util.SparseBooleanArray; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; -import android.view.OrientationEventListener; -import android.view.Surface; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; @@ -103,7 +103,6 @@ import com.android.launcher3.anim.SpringProperty; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statehandlers.DepthController; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.touch.PagedOrientationHandler.CurveProperties; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -191,8 +190,6 @@ public abstract class RecentsView extends PagedView impl }; protected final RecentsOrientedState mOrientationState; - private OrientationEventListener mOrientationListener; - private int mPreviousRotation; protected RecentsAnimationController mRecentsAnimationController; protected RecentsAnimationTargets mRecentsAnimationTargets; protected AppWindowAnimationHelper mAppWindowAnimationHelper; @@ -301,9 +298,6 @@ public abstract class RecentsView extends PagedView impl } }; - private final RecentsOrientedState.SystemRotationChangeListener mSystemRotationChangeListener = - enabled -> toggleOrientationEventListener(); - private final PinnedStackAnimationListener mIPinnedStackAnimationListener = new PinnedStackAnimationListener(); @@ -360,11 +354,13 @@ public abstract class RecentsView extends PagedView impl } }; - public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) { + public RecentsView(Context context, AttributeSet attrs, int defStyleAttr, + boolean rotationSupportedByActivity) { super(context, attrs, defStyleAttr); setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing)); setEnableFreeScroll(true); - mOrientationState = new RecentsOrientedState(context); + mOrientationState = new RecentsOrientedState( + context, rotationSupportedByActivity, this::animateRecentsRotationInPlace); mFastFlingVelocity = getResources() .getDimensionPixelSize(R.dimen.recents_fast_fling_velocity); @@ -399,21 +395,10 @@ public abstract class RecentsView extends PagedView impl .getDimensionPixelSize(R.dimen.recents_empty_message_text_padding); setWillNotDraw(false); updateEmptyMessage(); - disableMultipleLayoutRotations(!supportsVerticalLandscape()); + mOrientationHandler = mOrientationState.getOrientationHandler(); // Initialize quickstep specific cache params here, as this is constructed only once mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5); - - mOrientationListener = new OrientationEventListener(getContext()) { - @Override - public void onOrientationChanged(int i) { - int rotation = RecentsOrientedState.getRotationForUserDegreesRotated(i); - if (mPreviousRotation != rotation) { - animateRecentsRotationInPlace(rotation); - mPreviousRotation = rotation; - } - } - }; } public OverScroller getScroller() { @@ -502,7 +487,6 @@ public abstract class RecentsView extends PagedView impl SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener( mIPinnedStackAnimationListener); mOrientationState.init(); - mOrientationState.addSystemRotationChangeListener(mSystemRotationChangeListener); } @Override @@ -517,7 +501,6 @@ public abstract class RecentsView extends PagedView impl mIdp.removeOnChangeListener(this); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null); mIPinnedStackAnimationListener.setActivity(null); - mOrientationState.removeSystemRotationChangeListener(mSystemRotationChangeListener); mOrientationState.destroy(); } @@ -576,31 +559,12 @@ public abstract class RecentsView extends PagedView impl public void setOverviewStateEnabled(boolean enabled) { mOverviewStateEnabled = enabled; updateTaskStackListenerState(); + mOrientationState.setRotationWatcherEnabled(enabled); if (!enabled) { // Reset the running task when leaving overview since it can still have a reference to // its thumbnail mTmpRunningTask = null; } - toggleOrientationEventListener(); - } - - private void toggleOrientationEventListener() { - boolean canEnable = canEnableOverviewRotationAnimation() && mOverviewStateEnabled; - UI_HELPER_EXECUTOR.execute(() -> { - if (canEnable) { - mOrientationListener.enable(); - } else { - mOrientationListener.disable(); - } - }); - } - - private boolean canEnableOverviewRotationAnimation() { - return supportsVerticalLandscape() // not 3P launcher - && !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests.. - && mOrientationListener.canDetectOrientation() // ..but does the hardware even work? - && (mOrientationState.isSystemRotationAllowed() && - !mOrientationState.canLauncherRotate()); // launcher is going to rotate itself } public void onDigitalWellbeingToastShown() { @@ -730,7 +694,7 @@ public abstract class RecentsView extends PagedView impl final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex; final Task task = tasks.get(i); final TaskView taskView = (TaskView) getChildAt(pageIndex); - taskView.bind(task, mOrientationState); + taskView.bind(task, mOrientationState, mActivity.getDeviceProfile().isMultiWindowMode); } if (mNextPage == INVALID_PAGE) { @@ -820,9 +784,7 @@ public abstract class RecentsView extends PagedView impl for (int i = 0; i < taskCount; i++) { getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress); } - if (mActionsView != null && mOrientationState.getLauncherRotation() == Surface.ROTATION_0) { - mActionsView.setVisibility(fullscreenProgress == 0 ? VISIBLE : INVISIBLE); - } + mActionsView.updateHiddenFlags(HIDDEN_FULLESCREEN_PROGRESS, fullscreenProgress > 0); } private void updateTaskStackListenerState() { @@ -1039,10 +1001,6 @@ public abstract class RecentsView extends PagedView impl } private void animateRecentsRotationInPlace(int newRotation) { - if (!supportsVerticalLandscape()) { - return; - } - AnimatorSet pa = setRecentsChangedOrientation(true); pa.addListener(AnimationSuccessListener.forRunnable(() -> { setLayoutRotation(newRotation, mOrientationState.getDisplayRotation()); @@ -1067,7 +1025,6 @@ public abstract class RecentsView extends PagedView impl return as; } - abstract protected boolean supportsVerticalLandscape(); private void rotateAllChildTasks() { for (int i = 0; i < getTaskViewCount(); i++) { @@ -1111,7 +1068,8 @@ public abstract class RecentsView extends PagedView impl new ComponentName(getContext(), getClass()), 0, 0), null, null, "", "", 0, 0, false, true, false, false, new ActivityManager.TaskDescription(), 0, new ComponentName("", ""), false); - taskView.bind(mTmpRunningTask, mOrientationState); + taskView.bind(mTmpRunningTask, mOrientationState, + mActivity.getDeviceProfile().isMultiWindowMode); } boolean runningTaskTileHidden = mRunningTaskTileHidden; @@ -1611,17 +1569,12 @@ public abstract class RecentsView extends PagedView impl setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated()); mActivity.getDragLayer().recreateControllers(); - mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION, touchRotation != 0); + mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION, + touchRotation != 0 || launcherRotation != 0); requestLayout(); } } - public void disableMultipleLayoutRotations(boolean disable) { - mOrientationState.disableMultipleOrientations(disable); - mOrientationHandler = mOrientationState.getOrientationHandler(); - requestLayout(); - } - public RecentsOrientedState getPagedViewOrientedState() { return mOrientationState; } @@ -1719,6 +1672,13 @@ public abstract class RecentsView extends PagedView impl updateCurveProperties(); } + /** + * TODO: Do not assume motion across X axis for adjacent page + */ + public float getPageOffsetScale() { + return Math.max(getWidth(), 1); + } + private void updateDeadZoneRects() { // Get the deadzone rect surrounding the clear all button to not dismiss overview to home mClearAllButtonDeadZoneRect.setEmpty(); @@ -2083,8 +2043,7 @@ public abstract class RecentsView extends PagedView impl public Consumer getEventDispatcher(float navbarRotation) { float degreesRotated; if (navbarRotation == 0) { - degreesRotated = mOrientationState.areMultipleLayoutOrientationsDisabled() ? 0 : - mOrientationHandler.getDegreesRotated(); + degreesRotated = mOrientationHandler.getDegreesRotated(); } else { degreesRotated = -navbarRotation; } @@ -2097,7 +2056,7 @@ public abstract class RecentsView extends PagedView impl // PagedOrientationHandler return e -> { if (navbarRotation != 0 - && !mOrientationState.areMultipleLayoutOrientationsDisabled() + && mOrientationState.isMultipleOrientationSupportedByDevice() && !mOrientationState.getOrientationHandler().isLayoutNaturalToLauncher()) { mOrientationState.flipVertical(e); super.onTouchEvent(e); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java index 80022b4fe1..9b475205dd 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java @@ -40,6 +40,7 @@ import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.popup.SystemShortcut; +import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.TaskOverlayFactory; @@ -150,9 +151,26 @@ public class TaskMenuView extends AbstractFloatingView { return (type & TYPE_TASK_MENU) != 0; } - public void setPosition(float x, float y) { - setX(x); - setY(y + mThumbnailTopMargin); + public void setPosition(float x, float y, PagedOrientationHandler pagedOrientationHandler) { + float adjustedY = y + mThumbnailTopMargin; + // Changing pivot to make computations easier + // NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set, + // which would render the X and Y position set here incorrect + setPivotX(0); + setPivotY(0); + setRotation(pagedOrientationHandler.getDegreesRotated()); + setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail())); + setY(pagedOrientationHandler.getTaskMenuY(adjustedY, mTaskView.getThumbnail())); + } + + public void onRotationChanged() { + if (mOpenCloseAnimator != null && mOpenCloseAnimator.isRunning()) { + mOpenCloseAnimator.end(); + } + if (mIsOpen) { + mOptionLayout.removeAllViews(); + populateAndLayoutMenu(); + } } public static TaskMenuView showForTask(TaskView taskView) { @@ -168,12 +186,16 @@ public class TaskMenuView extends AbstractFloatingView { } mActivity.getDragLayer().addView(this); mTaskView = taskView; - addMenuOptions(mTaskView); - orientAroundTaskView(mTaskView); + populateAndLayoutMenu(); post(this::animateOpen); return true; } + private void populateAndLayoutMenu() { + addMenuOptions(mTaskView); + orientAroundTaskView(mTaskView); + } + private void addMenuOptions(TaskView taskView) { Drawable icon = taskView.getTask().icon.getConstantState().newDrawable(); mTaskIcon.setDrawable(icon); @@ -200,21 +222,26 @@ public class TaskMenuView extends AbstractFloatingView { R.layout.task_view_menu_option, this, false); menuOption.setIconAndLabelFor( menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text)); + LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams(); + mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp); menuOptionView.setOnClickListener(menuOption); mOptionLayout.addView(menuOptionView); } private void orientAroundTaskView(TaskView taskView) { + PagedOrientationHandler orientationHandler = taskView.getPagedOrientationHandler(); measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect); Rect insets = mActivity.getDragLayer().getInsets(); BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams(); - params.width = taskView.getMeasuredWidth(); + params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail()); params.gravity = Gravity.START; setLayoutParams(params); setScaleX(taskView.getScaleX()); setScaleY(taskView.getScaleY()); - setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top); + mOptionLayout.setOrientation(orientationHandler.getTaskMenuLayoutOrientation()); + setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, + taskView.getPagedOrientationHandler()); } private void animateOpen() { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java index a05e0fa4fc..e525842db0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java @@ -36,6 +36,7 @@ import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; import android.util.FloatProperty; +import android.util.Log; import android.util.Property; import android.view.Surface; import android.view.View; @@ -103,6 +104,7 @@ public class TaskThumbnailView extends View implements PluginListener 0) { - mExpectedHeight = h; - } else { - int m = MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY - 1, MeasureSpec.AT_MOST); - view.measure(m, m); - mExpectedHeight = view.getMeasuredHeight(); - } + mExpectedHeight = getExpectedViewHeight(view); mOldPaddingBottom = view.getPaddingBottom(); if (mOldOutlineProvider != null) { @@ -819,6 +898,19 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } } + private int getExpectedViewHeight(View view) { + int expectedHeight; + int h = view.getLayoutParams().height; + if (h > 0) { + expectedHeight = h; + } else { + int m = MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY - 1, MeasureSpec.AT_MOST); + view.measure(m, m); + expectedHeight = view.getMeasuredHeight(); + } + return expectedHeight; + } + @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); @@ -874,6 +966,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { return (RecentsView) getParent(); } + PagedOrientationHandler getPagedOrientationHandler() { + return getRecentsView().mOrientationState.getOrientationHandler(); + } + public void notifyTaskLaunchFailed(String tag) { String msg = "Failed to launch task"; if (mTask != null) { diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml index 69481ad49f..190290ebb4 100644 --- a/quickstep/res/layout/gesture_tutorial_fragment.xml +++ b/quickstep/res/layout/gesture_tutorial_fragment.xml @@ -18,6 +18,12 @@ android:layout_height="match_parent" android:background="@color/gesture_tutorial_background_color"> + + + +