diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 27224f2fed..c961302d3b 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -45,7 +45,7 @@ import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.states.StateAnimationConfig; -import com.android.launcher3.touch.PagedOrientationHandler; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.AnimUtils; import com.android.quickstep.util.SplitAnimationTimings; import com.android.quickstep.views.ClearAllButton; @@ -130,7 +130,7 @@ public final class RecentsViewStateController extends } // Create transition animations to split select - PagedOrientationHandler orientationHandler = + RecentsPagedOrientationHandler orientationHandler = ((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler(); Pair taskViewsFloat = orientationHandler.getSplitSelectTaskOffset( diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index ec84550898..ef5096b219 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -36,13 +36,13 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.touch.BaseSwipeDetector; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.touch.SingleAxisSwipeDetector; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.VibratorWrapper; import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.VibrationConstants; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; @@ -225,7 +225,8 @@ public abstract class TaskViewTouchController mCurrentAnimation.dispatchOnCancel(); } - PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + mRecentsView.getPagedOrientationHandler(); mCurrentAnimationIsGoingUp = goingUp; BaseDragLayer dl = mActivity.getDragLayer(); final int secondaryLayerDimension = orientationHandler.getSecondaryDimension(dl); @@ -269,7 +270,8 @@ public abstract class TaskViewTouchController @Override public void onDragStart(boolean start, float startDisplacement) { - PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + mRecentsView.getPagedOrientationHandler(); if (mCurrentAnimation == null) { reInitAnimationController(orientationHandler.isGoingUp(startDisplacement, mIsRtl)); mDisplacementShift = 0; @@ -283,7 +285,8 @@ public abstract class TaskViewTouchController @Override public boolean onDrag(float displacement) { - PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + mRecentsView.getPagedOrientationHandler(); float totalDisplacement = displacement + mDisplacementShift; boolean isGoingUp = totalDisplacement == 0 ? mCurrentAnimationIsGoingUp : orientationHandler.isGoingUp(totalDisplacement, mIsRtl); @@ -346,7 +349,8 @@ public abstract class TaskViewTouchController if (blockedFling) { fling = false; } - PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + mRecentsView.getPagedOrientationHandler(); boolean goingUp = orientationHandler.isGoingUp(velocity, mIsRtl); float progress = mCurrentAnimation.getProgressFraction(); float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress(); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 377b866d09..ca82a2d296 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -62,6 +62,7 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.views.ScrimView; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.views.RecentsView; @@ -128,7 +129,7 @@ public abstract class BaseActivityInterface T getPrimaryValue(T x, T y) { @@ -398,7 +400,7 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { @Override public ChildBounds getChildBounds(View child, int childStart, int pageCenter, - boolean layoutChild) { + boolean layoutChild) { final int childHeight = child.getMeasuredHeight(); final int childBottom = childStart + childHeight; final int childWidth = child.getMeasuredWidth(); @@ -574,21 +576,21 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { } @Override - public void setIconAppChipMenuParams(View iconAppChipMenuView, + public void setIconAppChipMenuParams(IconAppChipView iconAppChipView, FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin, int thumbnailTopMargin) { - boolean isRtl = iconAppChipMenuView.getLayoutDirection() == LAYOUT_DIRECTION_RTL; + boolean isRtl = iconAppChipView.getLayoutDirection() == LAYOUT_DIRECTION_RTL; iconMenuParams.gravity = (isRtl ? START : END) | (isRtl ? BOTTOM : TOP); iconMenuParams.setMarginStart(isRtl ? iconMenuMargin : 0); iconMenuParams.topMargin = iconMenuMargin; iconMenuParams.bottomMargin = isRtl ? iconMenuMargin : 0; iconMenuParams.setMarginEnd(iconMenuMargin); - iconAppChipMenuView.setPivotX(isRtl ? iconMenuParams.width - (iconMenuParams.height / 2f) + iconAppChipView.setPivotX(isRtl ? iconMenuParams.width - (iconMenuParams.height / 2f) : iconMenuParams.width / 2f); - iconAppChipMenuView.setPivotY( + iconAppChipView.setPivotY( isRtl ? (iconMenuParams.height / 2f) : iconMenuParams.width / 2f); - iconAppChipMenuView.setTranslationY(0); - iconAppChipMenuView.setRotation(getDegreesRotated()); + iconAppChipView.setTranslationY(0); + iconAppChipView.setRotation(getDegreesRotated()); } @Override diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java similarity index 90% rename from src/com/android/launcher3/touch/PortraitPagedViewHandler.java rename to quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java index 8301981d31..3d7065b82a 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.launcher3.touch; +package com.android.quickstep.orientation; import static android.view.Gravity.BOTTOM; import static android.view.Gravity.CENTER_HORIZONTAL; @@ -33,7 +33,6 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN; -import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; @@ -42,26 +41,27 @@ import android.graphics.drawable.ShapeDrawable; import android.util.FloatProperty; import android.util.Pair; import android.view.Gravity; -import android.view.MotionEvent; import android.view.Surface; -import android.view.VelocityTracker; import android.view.View; -import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import android.widget.LinearLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.touch.DefaultPagedViewHandler; +import com.android.launcher3.touch.SingleAxisSwipeDetector; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; +import com.android.quickstep.views.IconAppChipView; import java.util.ArrayList; import java.util.List; -public class PortraitPagedViewHandler implements PagedOrientationHandler { +public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements + RecentsPagedOrientationHandler { private final Matrix mTmpMatrix = new Matrix(); private final RectF mTmpRectF = new RectF(); @@ -75,27 +75,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { public T getSecondaryValue(T x, T y) { return y; } - - @Override - public int getPrimaryValue(int x, int y) { - return x; - } - - @Override - public int getSecondaryValue(int x, int y) { - return y; - } - - @Override - public float getPrimaryValue(float x, float y) { - return x; - } - - @Override - public float getSecondaryValue(float x, float y) { - return y; - } - @Override public boolean isLayoutNaturalToLauncher() { return true; @@ -115,16 +94,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } } - @Override - public void setPrimary(T target, Int2DAction action, int param) { - action.call(target, param, 0); - } - - @Override - public void setPrimary(T target, Float2DAction action, float param) { - action.call(target, param, 0); - } - @Override public void setSecondary(T target, Float2DAction action, float param) { action.call(target, 0, param); @@ -136,21 +105,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { action.call(target, primaryParam, secondaryParam); } - @Override - public float getPrimaryDirection(MotionEvent event, int pointerIndex) { - return event.getX(pointerIndex); - } - - @Override - public float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId) { - return velocityTracker.getXVelocity(pointerId); - } - - @Override - public int getMeasuredSize(View view) { - return view.getMeasuredWidth(); - } - @Override public int getPrimarySize(View view) { return view.getWidth(); @@ -191,26 +145,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { return VIEW_TRANSLATE_Y; } - @Override - public int getPrimaryScroll(View view) { - return view.getScrollX(); - } - - @Override - public float getPrimaryScale(View view) { - return view.getScaleX(); - } - - @Override - public void setMaxScroll(AccessibilityEvent event, int maxScroll) { - event.setMaxScrollX(maxScroll); - } - - @Override - public boolean getRecentsRtlSetting(Resources resources) { - return !Utilities.isRtl(resources); - } - @Override public float getDegreesRotated() { return 0; @@ -231,27 +165,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { view.setScaleY(scale); } - @Override - public int getChildStart(View view) { - return view.getLeft(); - } - - @Override - public int getCenterForPage(View view, Rect insets) { - return (view.getPaddingTop() + view.getMeasuredHeight() + insets.top - - insets.bottom - view.getPaddingBottom()) / 2; - } - - @Override - public int getScrollOffsetStart(View view, Rect insets) { - return insets.left + view.getPaddingLeft(); - } - - @Override - public int getScrollOffsetEnd(View view, Rect insets) { - return view.getWidth() - view.getPaddingRight() - insets.right; - } - public int getSecondaryTranslationDirectionFactor() { return -1; } @@ -400,20 +313,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } /* -------------------- */ - - @Override - public ChildBounds getChildBounds(View child, int childStart, int pageCenter, - boolean layoutChild) { - final int childWidth = child.getMeasuredWidth(); - final int childRight = childStart + childWidth; - final int childHeight = child.getMeasuredHeight(); - final int childTop = pageCenter - childHeight / 2; - if (layoutChild) { - child.layout(childStart, childTop, childRight, childTop + childHeight); - } - return new ChildBounds(childWidth, childHeight, childRight, childTop); - } - @Override public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) { return dp.heightPx - rect.bottom; @@ -713,7 +612,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } @Override - public void setIconAppChipMenuParams(View iconAppChipMenuView, + public void setIconAppChipMenuParams(IconAppChipView iconAppChipView, FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin, int thumbnailTopMargin) { iconMenuParams.gravity = TOP | START; iconMenuParams.setMarginStart(iconMenuMargin); @@ -721,10 +620,10 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { iconMenuParams.bottomMargin = 0; iconMenuParams.setMarginEnd(0); - iconAppChipMenuView.setPivotX(0); - iconAppChipMenuView.setPivotY(0); - iconAppChipMenuView.setTranslationY(0); - iconAppChipMenuView.setRotation(getDegreesRotated()); + iconAppChipView.setPivotX(0); + iconAppChipView.setPivotY(0); + iconAppChipView.setTranslationY(0); + iconAppChipView.setRotation(getDegreesRotated()); } @Override diff --git a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java new file mode 100644 index 0000000000..34756b4f3f --- /dev/null +++ b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.quickstep.orientation; + + +import android.graphics.PointF; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.ShapeDrawable; +import android.util.FloatProperty; +import android.util.Pair; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.LinearLayout; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.touch.PagedOrientationHandler; +import com.android.launcher3.touch.SingleAxisSwipeDetector; +import com.android.launcher3.util.SplitConfigurationOptions; +import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; +import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; +import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; +import com.android.quickstep.views.IconAppChipView; + +import java.util.List; + +/** + * Abstraction layer to separate horizontal and vertical specific implementations + * for {@link com.android.quickstep.views.RecentsView}. Majority of these implementations are + * (should be) as simple as choosing the correct X and Y analogous methods. + */ +public interface RecentsPagedOrientationHandler extends PagedOrientationHandler { + + RecentsPagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler(); + RecentsPagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler(); + RecentsPagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler(); + + void setSecondary(T target, Float2DAction action, float param); + void set(T target, Int2DAction action, int primaryParam, int secondaryParam); + int getPrimarySize(View view); + float getPrimarySize(RectF rect); + int getSecondaryTranslationDirectionFactor(); + float getDegreesRotated(); + int getRotation(); + boolean isLayoutNaturalToLauncher(); + + T getPrimaryValue(T x, T y); + T getSecondaryValue(T x, T y); + void setPrimaryScale(View view, float scale); + void setSecondaryScale(View view, float scale); + float getStart(RectF rect); + float getEnd(RectF rect); + int getClearAllSidePadding(View view, boolean isRtl); + int getSecondaryDimension(View view); + FloatProperty getPrimaryViewTranslate(); + FloatProperty getSecondaryViewTranslate(); + int getSplitTranslationDirectionFactor(@StagePosition int stagePosition, + DeviceProfile deviceProfile); + Pair getSplitSelectTaskOffset(FloatProperty primary, + FloatProperty secondary, DeviceProfile deviceProfile); + int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect); + List getSplitPositionOptions(DeviceProfile dp); + /** + * @param placeholderHeight height of placeholder view in portrait, width in landscape + */ + void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset, + DeviceProfile dp, @StagePosition int stagePosition, Rect out); + + /** + * Centers an icon in the split staging area, accounting for insets. + * @param out The icon that needs to be centered. + * @param onScreenRectCenterX The x-center of the on-screen staging area (most of the Rect is + * offscreen). + * @param onScreenRectCenterY The y-center of the on-screen staging area (most of the Rect is + * offscreen). + * @param fullscreenScaleX A x-scaling factor used to convert coordinates back into pixels. + * @param fullscreenScaleY A y-scaling factor used to convert coordinates back into pixels. + * @param drawableWidth The icon's drawable (final) width. + * @param drawableHeight The icon's drawable (final) height. + * @param dp The device profile, used to report rotation and hardware insets. + * @param stagePosition 0 if the staging area is pinned to top/left, 1 for bottom/right. + */ + void updateSplitIconParams(View out, float onScreenRectCenterX, + float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY, + int drawableWidth, int drawableHeight, DeviceProfile dp, + @StagePosition int stagePosition); + + /** + * Sets positioning and rotation for a SplitInstructionsView. + * @param out The SplitInstructionsView that needs to be positioned. + * @param dp The device profile, used to report rotation and device type. + * @param splitInstructionsHeight The SplitInstructionView's height. + * @param splitInstructionsWidth The SplitInstructionView's width. + */ + void setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight, + int splitInstructionsWidth); + + /** + * @param splitDividerSize height of split screen drag handle in portrait, width in landscape + * @param stagePosition the split position option (top/left, bottom/right) of the first + * task selected for entering split + * @param out1 the bounds for where the first selected app will be + * @param out2 the bounds for where the second selected app will be, complimentary to + * {@param out1} based on {@param initialSplitOption} + */ + void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp, + @StagePosition int stagePosition, Rect out1, Rect out2); + + int getDefaultSplitPosition(DeviceProfile deviceProfile); + + /** + * @param outRect This is expected to be the rect that has the dimensions for a non-split, + * fullscreen task in overview. This will directly be modified. + * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize + * outRect for + */ + void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect, SplitBounds splitInfo, + @SplitConfigurationOptions.StagePosition int desiredStagePosition); + + void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, + int parentWidth, int parentHeight, + SplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl); + + // Overview TaskMenuView methods + void setTaskIconParams(FrameLayout.LayoutParams iconParams, + int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl); + + void setIconAppChipMenuParams(IconAppChipView iconAppChipView, + FrameLayout.LayoutParams iconMenuParams, + int iconMenuMargin, int thumbnailTopMargin); + void setSplitIconParams(View primaryIconView, View secondaryIconView, + int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight, + int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl, + DeviceProfile deviceProfile, SplitBounds splitConfig); + + /* + * The following two methods try to center the TaskMenuView in landscape by finding the center + * of the thumbnail view and then subtracting half of the taskMenu width. In this case, the + * taskMenu width is the same size as the thumbnail width (what got set below in + * getTaskMenuWidth()), so we directly use that in the calculations. + */ + float getTaskMenuX(float x, View thumbnailView, DeviceProfile deviceProfile, + float taskInsetMargin, View taskViewIcon); + float getTaskMenuY(float y, View thumbnailView, int stagePosition, + View taskMenuView, float taskInsetMargin, View taskViewIcon); + int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile, + @StagePosition int stagePosition); + /** + * Sets linear layout orientation for {@link com.android.launcher3.popup.SystemShortcut} items + * inside task menu view. + */ + void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile, + LinearLayout taskMenuLayout, int dividerSpacing, + ShapeDrawable dividerDrawable); + /** + * Sets layout param attributes for {@link com.android.launcher3.popup.SystemShortcut} child + * views inside task menu view. + */ + void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp, + LinearLayout viewGroup, DeviceProfile deviceProfile); + + /** + * Calculates the position where a Digital Wellbeing Banner should be placed on its parent + * TaskView. + * @return A Pair of Floats representing the proper x and y translations. + */ + Pair getDwbLayoutTranslations(int taskViewWidth, + int taskViewHeight, SplitBounds splitBounds, DeviceProfile deviceProfile, + View[] thumbnailViews, int desiredTaskId, View banner); + + // The following are only used by TaskViewTouchHandler. + /** @return Either VERTICAL or HORIZONTAL. */ + SingleAxisSwipeDetector.Direction getUpDownSwipeDirection(); + /** @return Given {@link #getUpDownSwipeDirection()}, whether POSITIVE or NEGATIVE is up. */ + int getUpDirection(boolean isRtl); + /** @return Whether the displacement is going towards the top of the screen. */ + boolean isGoingUp(float displacement, boolean isRtl); + /** @return Either 1 or -1, a factor to multiply by so the animation goes the correct way. */ + int getTaskDragDisplacementFactor(boolean isRtl); + + /** + * Maps the velocity from the coordinate plane of the foreground app to that + * of Launcher's (which now will always be portrait) + */ + void adjustFloatingIconStartVelocity(PointF velocity); + + /** + * Ensures that outStartRect left bound is within the DeviceProfile's visual boundaries + * @param outStartRect The start rect that will directly be modified + */ + void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile); + + /** + * Determine the target translation for animating the FloatingTaskView out. This value could + * either be an x-coordinate or a y-coordinate, depending on which way the FloatingTaskView was + * docked. + * + * @param floatingTask The FloatingTaskView. + * @param onScreenRect The current on-screen dimensions of the FloatingTaskView. + * @param stagePosition STAGE_POSITION_TOP_OR_LEFT or STAGE_POSITION_BOTTOM_OR_RIGHT. + * @param dp The device profile. + * @return A float. When an animation translates the FloatingTaskView to this position, it will + * appear to tuck away off the edge of the screen. + */ + float getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect, + @StagePosition int stagePosition, DeviceProfile dp); + + /** + * Sets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be + * either x or y), depending on how the view is oriented. + * + * @param floatingTask The FloatingTaskView to be translated. + * @param translation The target translation value. + * @param dp The current device profile. + */ + void setFloatingTaskPrimaryTranslation(View floatingTask, float translation, DeviceProfile dp); + + /** + * Gets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be + * either x or y), depending on how the view is oriented. + * + * @param floatingTask The FloatingTaskView in question. + * @param dp The current device profile. + * @return The current translation value. + */ + Float getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp); +} diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java similarity index 96% rename from src/com/android/launcher3/touch/SeascapePagedViewHandler.java rename to quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java index 7077ad985a..7e53cf1ade 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.launcher3.touch; +package com.android.quickstep.orientation; import static android.view.Gravity.BOTTOM; import static android.view.Gravity.CENTER_VERTICAL; @@ -42,10 +42,12 @@ import android.widget.FrameLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.touch.SingleAxisSwipeDetector; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.views.IconAppChipView; import java.util.Collections; import java.util.List; @@ -234,9 +236,9 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { } @Override - public void setIconAppChipMenuParams(View iconAppChipMenuView, + public void setIconAppChipMenuParams(IconAppChipView iconAppChipView, FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin, int thumbnailTopMargin) { - boolean isRtl = iconAppChipMenuView.getLayoutDirection() == LAYOUT_DIRECTION_RTL; + boolean isRtl = iconAppChipView.getLayoutDirection() == LAYOUT_DIRECTION_RTL; iconMenuParams.gravity = (isRtl ? TOP : BOTTOM) | (isRtl ? END : START); iconMenuParams.setMarginStart(0); iconMenuParams.topMargin = isRtl ? iconMenuMargin : 0; @@ -244,12 +246,12 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { iconMenuParams.setMarginEnd(isRtl ? thumbnailTopMargin : 0); // Use half menu height to place the pivot within the X/Y center of icon in the menu. - float iconCenter = iconAppChipMenuView.getHeight() / 2f; - iconAppChipMenuView.setPivotX(isRtl ? iconMenuParams.width / 2f : iconCenter); - iconAppChipMenuView.setPivotY( + float iconCenter = iconAppChipView.getHeight() / 2f; + iconAppChipView.setPivotX(isRtl ? iconMenuParams.width / 2f : iconCenter); + iconAppChipView.setPivotY( isRtl ? iconMenuParams.width / 2f : iconCenter - iconMenuMargin); - iconAppChipMenuView.setTranslationY(0); - iconAppChipMenuView.setRotation(getDegreesRotated()); + iconAppChipView.setTranslationY(0); + iconAppChipView.setRotation(getDegreesRotated()); } @Override diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java index cb35ec8455..bc8b5710f3 100644 --- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java +++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java @@ -43,7 +43,7 @@ import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.AllAppsSwipeController; -import com.android.launcher3.touch.PagedOrientationHandler; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.views.RecentsView; /** @@ -200,7 +200,7 @@ public class AnimatorControllerWithResistance { public static PendingAnimation createRecentsResistanceAnim( RecentsParams params) { Rect startRect = new Rect(); - PagedOrientationHandler orientationHandler = params.recentsOrientedState + RecentsPagedOrientationHandler orientationHandler = params.recentsOrientedState .getOrientationHandler(); params.recentsOrientedState.getActivityInterface() .calculateTaskSize(params.context, params.dp, startRect, orientationHandler); diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java index 79656c27a4..ec1eeb1d6b 100644 --- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java +++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java @@ -21,10 +21,10 @@ import android.view.View; import android.view.ViewGroup; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.NavigationMode; import com.android.quickstep.LauncherActivityInterface; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; public class LayoutUtils { @@ -40,7 +40,7 @@ public class LayoutUtils { } public static int getShelfTrackingDistance(Context context, DeviceProfile dp, - PagedOrientationHandler orientationHandler) { + RecentsPagedOrientationHandler orientationHandler) { // Track the bottom of the window. Rect taskSize = new Rect(); LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, taskSize, diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index f6ad692fcb..cba628b817 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -53,6 +53,7 @@ import com.android.launcher3.util.SettingsCache; import com.android.quickstep.BaseActivityInterface; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskAnimationManager; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import java.lang.annotation.Retention; import java.util.function.IntConsumer; @@ -75,7 +76,8 @@ public class RecentsOrientedState implements @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) public @interface SurfaceRotation {} - private PagedOrientationHandler mOrientationHandler = PagedOrientationHandler.PORTRAIT; + private RecentsPagedOrientationHandler mOrientationHandler = + RecentsPagedOrientationHandler.PORTRAIT; private @SurfaceRotation int mTouchRotation = ROTATION_0; private @SurfaceRotation int mDisplayRotation = ROTATION_0; @@ -225,13 +227,13 @@ public class RecentsOrientedState implements private boolean updateHandler() { mRecentsActivityRotation = inferRecentsActivityRotation(mDisplayRotation); if (mRecentsActivityRotation == mTouchRotation || isRecentsActivityRotationAllowed()) { - mOrientationHandler = PagedOrientationHandler.PORTRAIT; + mOrientationHandler = RecentsPagedOrientationHandler.PORTRAIT; } else if (mTouchRotation == ROTATION_90) { - mOrientationHandler = PagedOrientationHandler.LANDSCAPE; + mOrientationHandler = RecentsPagedOrientationHandler.LANDSCAPE; } else if (mTouchRotation == ROTATION_270) { - mOrientationHandler = PagedOrientationHandler.SEASCAPE; + mOrientationHandler = RecentsPagedOrientationHandler.SEASCAPE; } else { - mOrientationHandler = PagedOrientationHandler.PORTRAIT; + mOrientationHandler = RecentsPagedOrientationHandler.PORTRAIT; } if (DEBUG) { Log.d(TAG, "current RecentsOrientedState: " + this); @@ -413,7 +415,7 @@ public class RecentsOrientedState implements return scale; } - public PagedOrientationHandler getOrientationHandler() { + public RecentsPagedOrientationHandler getOrientationHandler() { return mOrientationHandler; } diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java index fba847f04e..32ef904e10 100644 --- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java +++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java @@ -25,7 +25,7 @@ import android.widget.Button; import com.android.launcher3.DeviceProfile; import com.android.launcher3.statemanager.StatefulActivity; -import com.android.launcher3.touch.PagedOrientationHandler; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; public class ClearAllButton extends Button { @@ -81,7 +81,8 @@ public class ClearAllButton extends Button { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - PagedOrientationHandler orientationHandler = getRecentsView().getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + getRecentsView().getPagedOrientationHandler(); mSidePadding = orientationHandler.getClearAllSidePadding(getRecentsView(), mIsRtl); } @@ -131,7 +132,8 @@ public class ClearAllButton extends Button { return; } - PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + recentsView.getPagedOrientationHandler(); float orientationSize = orientationHandler.getPrimaryValue(getWidth(), getHeight()); if (orientationSize == 0) { return; @@ -219,7 +221,8 @@ public class ClearAllButton extends Button { return; } - PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + recentsView.getPagedOrientationHandler(); orientationHandler.getPrimaryViewTranslate().set(this, orientationHandler.getPrimaryValue(0f, getOriginalTranslationY()) + mNormalTranslationPrimary + getFullscreenTrans( @@ -232,7 +235,8 @@ public class ClearAllButton extends Button { return; } - PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + recentsView.getPagedOrientationHandler(); orientationHandler.getSecondaryViewTranslate().set(this, orientationHandler.getSecondaryValue(0f, getOriginalTranslationY())); } diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java index 937a7281b6..840382d141 100644 --- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java +++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java @@ -50,8 +50,8 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.systemui.shared.recents.model.Task; import java.lang.annotation.Retention; @@ -321,7 +321,7 @@ public final class DigitalWellBeingToast { DeviceProfile deviceProfile = mActivity.getDeviceProfile(); layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams) mTaskView.getThumbnail().getLayoutParams()).bottomMargin; - PagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler(); Pair translations = orientationHandler .getDwbLayoutTranslations(mTaskView.getMeasuredWidth(), mTaskView.getMeasuredHeight(), mSplitBounds, deviceProfile, diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java index efc0a35ffe..12a073fa84 100644 --- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java +++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java @@ -43,9 +43,9 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarActivityContext; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.AnimUtils; import com.android.quickstep.util.MultiValueUpdateListener; import com.android.quickstep.util.SplitAnimationTimings; @@ -95,7 +95,7 @@ public class FloatingTaskView extends FrameLayout { private final StatefulActivity mActivity; private final boolean mIsRtl; private final FullscreenDrawParams mFullscreenParams; - private PagedOrientationHandler mOrientationHandler; + private RecentsPagedOrientationHandler mOrientationHandler; @SplitConfigurationOptions.StagePosition private int mStagePosition; private final Rect mTmpRect = new Rect(); @@ -220,7 +220,7 @@ public class FloatingTaskView extends FrameLayout { mOrientationHandler.setSecondaryScale(mSplitPlaceholderView.getIconView(), childScaleY); } - public void updateOrientationHandler(PagedOrientationHandler orientationHandler) { + public void updateOrientationHandler(RecentsPagedOrientationHandler orientationHandler) { mOrientationHandler = orientationHandler; mSplitPlaceholderView.getIconView().setRotation(mOrientationHandler.getDegreesRotated()); } diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.java b/quickstep/src/com/android/quickstep/views/IconAppChipView.java index ee09c4dedd..d2b0540702 100644 --- a/quickstep/src/com/android/quickstep/views/IconAppChipView.java +++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.java @@ -39,9 +39,9 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.views.ActivityContext; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.RecentsOrientedState; /** @@ -211,7 +211,8 @@ public class IconAppChipView extends FrameLayout implements TaskViewIcon { @Override public void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask) { - PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + orientationState.getOrientationHandler(); boolean isRtl = isLayoutRtl(); DeviceProfile deviceProfile = ActivityContext.lookupContext(getContext()).getDeviceProfile(); diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java index a4bda7f267..042f58170b 100644 --- a/quickstep/src/com/android/quickstep/views/IconView.java +++ b/quickstep/src/com/android/quickstep/views/IconView.java @@ -30,8 +30,8 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Utilities; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.views.ActivityContext; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.RecentsOrientedState; /** @@ -173,7 +173,8 @@ public class IconView extends View implements TaskViewIcon { @Override public void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask) { - PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + orientationState.getOrientationHandler(); boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; DeviceProfile deviceProfile = ActivityContext.lookupContext(getContext()).getDeviceProfile(); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 6b3484d388..66d651e944 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -156,7 +156,6 @@ import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.OverScroll; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; @@ -187,6 +186,7 @@ import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.TaskViewUtils; import com.android.quickstep.TopTaskTracker; import com.android.quickstep.ViewUtils; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.ActiveGestureErrorDetector; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.AnimUtils; @@ -788,7 +788,8 @@ public abstract class RecentsView(context, this, R.layout.task_desktop, 5 /* max size */, 1 /* initial size */); - mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources()); + setOrientationHandler(mOrientationState.getOrientationHandler()); + mIsRtl = getPagedOrientationHandler().getRecentsRtlSetting(getResources()); setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); mSplitPlaceholderSize = getResources().getDimensionPixelSize( R.dimen.split_placeholder_size); @@ -812,7 +813,6 @@ public abstract class RecentsView= start && taskStart <= end) || (taskEnd >= start && taskEnd <= end); } private boolean isTaskViewFullyWithinBounds(TaskView tv, int start, int end) { - int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment( - showAsGrid()); - int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment( - showAsFullscreen())); + int taskStart = getPagedOrientationHandler().getChildStart(tv) + + (int) tv.getOffsetAdjustment(showAsGrid()); + int taskSize = (int) (getPagedOrientationHandler().getMeasuredSize(tv) + * tv.getSizeAdjustment(showAsFullscreen())); int taskEnd = taskStart + taskSize; return taskStart >= start && taskEnd <= end; } @@ -1628,7 +1628,7 @@ public abstract class RecentsView secondaryViewTranslate = taskView.getSecondaryDismissTranslationProperty(); - int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView); - int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor(); + int secondaryTaskDimension = getPagedOrientationHandler().getSecondaryDimension(taskView); + int verticalFactor = getPagedOrientationHandler().getSecondaryTranslationDirectionFactor(); ResourceProvider rp = DynamicResource.provider(mActivity); SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START) @@ -3248,7 +3248,7 @@ public abstract class RecentsView remoteTargetHandle.getTaskViewSimulator() - .taskSecondaryTranslation.value = mOrientationHandler + .taskSecondaryTranslation.value = getPagedOrientationHandler() .getSecondaryValue(taskView.getTranslationX(), taskView.getTranslationY() )); @@ -3262,7 +3262,7 @@ public abstract class RecentsView lastTaskScroll)) { @@ -3597,7 +3597,7 @@ public abstract class RecentsView remoteTargetHandle.getTaskViewSimulator() .taskPrimaryTranslation.value = - mOrientationHandler.getPrimaryValue( + getPagedOrientationHandler().getPrimaryValue( child.getTranslationX(), child.getTranslationY() )); @@ -3709,7 +3709,7 @@ public abstract class RecentsView taskViewsFloat = orientationHandler.getSplitSelectTaskOffset( TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION, @@ -5059,7 +5063,7 @@ public abstract class RecentsView= 0 && otherAdjacentTaskIndex < getPageCount()) { PropertyValuesHolder[] properties = new PropertyValuesHolder[3]; properties[0] = PropertyValuesHolder.ofFloat( - mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation); + getPagedOrientationHandler().getPrimaryViewTranslate(), primaryTranslation); properties[1] = PropertyValuesHolder.ofFloat(View.SCALE_X, 1); properties[2] = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1); @@ -5495,8 +5499,8 @@ public abstract class RecentsView getEventDispatcher(float navbarRotation) { float degreesRotated; if (navbarRotation == 0) { - degreesRotated = mOrientationHandler.getDegreesRotated(); + degreesRotated = getPagedOrientationHandler().getDegreesRotated(); } else { degreesRotated = -navbarRotation; } diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java index 77033b2fa2..d7792765a6 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java +++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java @@ -48,10 +48,10 @@ import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.popup.SystemShortcut; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.TaskOverlayFactory; import com.android.quickstep.TaskUtils; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.TaskCornerRadius; import com.android.quickstep.views.TaskView.TaskIdAttributeContainer; @@ -215,7 +215,8 @@ public class TaskMenuView extends AbstractFloatingView { private void orientAroundTaskView(TaskIdAttributeContainer taskContainer) { RecentsView recentsView = mActivity.getOverviewPanel(); - PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); + RecentsPagedOrientationHandler orientationHandler = + recentsView.getPagedOrientationHandler(); measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); // Get Position diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index dff05807d6..077247b09a 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -51,11 +51,11 @@ import androidx.core.graphics.ColorUtils; import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Utilities; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.SystemUiController.SystemUiControllerFlags; import com.android.quickstep.TaskOverlayFactory.TaskOverlay; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.views.TaskView.FullscreenDrawParams; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -513,7 +513,7 @@ public class TaskThumbnailView extends View { return false; } - if (recents.getPagedOrientationHandler() == PagedOrientationHandler.PORTRAIT) { + if (recents.getPagedOrientationHandler() == RecentsPagedOrientationHandler.PORTRAIT) { int currentRotation = recents.getPagedViewOrientedState().getRecentsActivityRotation(); return (currentRotation - mThumbnailData.rotation) % 2 != 0; } else { diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index f2c0286e60..11e721e18e 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -87,7 +87,6 @@ import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; -import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.ActivityOptionsWrapper; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.RunnableList; @@ -104,6 +103,7 @@ import com.android.quickstep.TaskIconCache; import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.TaskUtils; import com.android.quickstep.TaskViewUtils; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.BorderAnimator; import com.android.quickstep.util.CancellableTask; @@ -116,6 +116,8 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; +import kotlin.Unit; + import java.lang.annotation.Retention; import java.util.Arrays; import java.util.Collections; @@ -124,8 +126,6 @@ import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; -import kotlin.Unit; - /** * A task in the Recents view. */ @@ -1660,7 +1660,7 @@ public class TaskView extends FrameLayout implements Reusable { return (RecentsView) getParent(); } - PagedOrientationHandler getPagedOrientationHandler() { + RecentsPagedOrientationHandler getPagedOrientationHandler() { return getRecentsView().mOrientationState.getOrientationHandler(); } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index f355ae7128..43dca5cede 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -118,7 +118,8 @@ public abstract class PagedView extends ViewGrou private float mTotalMotion; // Used in special cases where the fling checks can be relaxed for an intentional gesture private boolean mAllowEasyFling; - protected PagedOrientationHandler mOrientationHandler = PagedOrientationHandler.PORTRAIT; + private PagedOrientationHandler mOrientationHandler = + PagedOrientationHandler.DEFAULT; private final ArrayList mOnPageScrollsInitializedCallbacks = new ArrayList<>(); @@ -231,6 +232,14 @@ public abstract class PagedView extends ViewGrou return getChildAt(index); } + protected PagedOrientationHandler getPagedOrientationHandler() { + return mOrientationHandler; + } + + protected void setOrientationHandler(PagedOrientationHandler orientationHandler) { + this.mOrientationHandler = orientationHandler; + } + /** * Updates the scroll of the current page immediately to its final scroll position. We use this * in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of diff --git a/src/com/android/launcher3/touch/DefaultPagedViewHandler.java b/src/com/android/launcher3/touch/DefaultPagedViewHandler.java new file mode 100644 index 0000000000..272ed10b5b --- /dev/null +++ b/src/com/android/launcher3/touch/DefaultPagedViewHandler.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.touch; + +import android.content.res.Resources; +import android.graphics.Rect; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.accessibility.AccessibilityEvent; + +import com.android.launcher3.Utilities; + +public class DefaultPagedViewHandler implements PagedOrientationHandler { + @Override + public int getPrimaryValue(int x, int y) { + return x; + } + + @Override + public int getSecondaryValue(int x, int y) { + return y; + } + + @Override + public float getPrimaryValue(float x, float y) { + return x; + } + + @Override + public float getSecondaryValue(float x, float y) { + return y; + } + + @Override + public void setPrimary(T target, Int2DAction action, int param) { + action.call(target, param, 0); + } + + @Override + public void setPrimary(T target, Float2DAction action, float param) { + action.call(target, param, 0); + } + + @Override + public float getPrimaryDirection(MotionEvent event, int pointerIndex) { + return event.getX(pointerIndex); + } + + @Override + public float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId) { + return velocityTracker.getXVelocity(pointerId); + } + + @Override + public int getMeasuredSize(View view) { + return view.getMeasuredWidth(); + } + + @Override + public int getPrimaryScroll(View view) { + return view.getScrollX(); + } + + @Override + public float getPrimaryScale(View view) { + return view.getScaleX(); + } + + @Override + public void setMaxScroll(AccessibilityEvent event, int maxScroll) { + event.setMaxScrollX(maxScroll); + } + + @Override + public boolean getRecentsRtlSetting(Resources resources) { + return !Utilities.isRtl(resources); + } + + @Override + public int getChildStart(View view) { + return view.getLeft(); + } + + @Override + public int getCenterForPage(View view, Rect insets) { + return (view.getPaddingTop() + view.getMeasuredHeight() + insets.top + - insets.bottom - view.getPaddingBottom()) / 2; + } + + @Override + public int getScrollOffsetStart(View view, Rect insets) { + return insets.left + view.getPaddingLeft(); + } + + @Override + public int getScrollOffsetEnd(View view, Rect insets) { + return view.getWidth() - view.getPaddingRight() - insets.right; + } + + @Override + public ChildBounds getChildBounds(View child, int childStart, int pageCenter, + boolean layoutChild) { + final int childWidth = child.getMeasuredWidth(); + final int childRight = childStart + childWidth; + final int childHeight = child.getMeasuredHeight(); + final int childTop = pageCenter - childHeight / 2; + if (layoutChild) { + child.layout(childStart, childTop, childRight, childTop + childHeight); + } + return new ChildBounds(childWidth, childHeight, childRight, childTop); + } + +} diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index 74d88ba922..e0c4e3c06b 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -19,26 +19,11 @@ package com.android.launcher3.touch; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Matrix; -import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.ShapeDrawable; -import android.util.FloatProperty; -import android.util.Pair; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.accessibility.AccessibilityEvent; -import android.widget.FrameLayout; -import android.widget.LinearLayout; - -import com.android.launcher3.DeviceProfile; -import com.android.launcher3.util.SplitConfigurationOptions; -import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; -import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; -import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; - -import java.util.List; /** * Abstraction layer to separate horizontal and vertical specific implementations @@ -47,9 +32,7 @@ import java.util.List; */ public interface PagedOrientationHandler { - PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler(); - PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler(); - PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler(); + PagedOrientationHandler DEFAULT = new DefaultPagedViewHandler(); interface Int2DAction { void call(T target, int x, int y); @@ -64,39 +47,18 @@ public interface PagedOrientationHandler { void setPrimary(T target, Int2DAction action, int param); void setPrimary(T target, Float2DAction action, float param); - void setSecondary(T target, Float2DAction action, float param); - void set(T target, Int2DAction action, int primaryParam, int secondaryParam); float getPrimaryDirection(MotionEvent event, int pointerIndex); float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId); int getMeasuredSize(View view); - int getPrimarySize(View view); - float getPrimarySize(RectF rect); - float getStart(RectF rect); - float getEnd(RectF rect); - int getClearAllSidePadding(View view, boolean isRtl); - int getSecondaryDimension(View view); - FloatProperty getPrimaryViewTranslate(); - FloatProperty getSecondaryViewTranslate(); - int getPrimaryScroll(View view); float getPrimaryScale(View view); int getChildStart(View view); int getCenterForPage(View view, Rect insets); int getScrollOffsetStart(View view, Rect insets); int getScrollOffsetEnd(View view, Rect insets); - int getSecondaryTranslationDirectionFactor(); - int getSplitTranslationDirectionFactor(@StagePosition int stagePosition, - DeviceProfile deviceProfile); ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild); void setMaxScroll(AccessibilityEvent event, int maxScroll); boolean getRecentsRtlSetting(Resources resources); - float getDegreesRotated(); - int getRotation(); - void setPrimaryScale(View view, float scale); - void setSecondaryScale(View view, float scale); - - T getPrimaryValue(T x, T y); - T getSecondaryValue(T x, T y); int getPrimaryValue(int x, int y); int getSecondaryValue(int x, int y); @@ -104,174 +66,6 @@ public interface PagedOrientationHandler { float getPrimaryValue(float x, float y); float getSecondaryValue(float x, float y); - boolean isLayoutNaturalToLauncher(); - Pair getSplitSelectTaskOffset(FloatProperty primary, - FloatProperty secondary, DeviceProfile deviceProfile); - int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect); - List getSplitPositionOptions(DeviceProfile dp); - /** - * @param placeholderHeight height of placeholder view in portrait, width in landscape - */ - void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset, - DeviceProfile dp, @StagePosition int stagePosition, Rect out); - - /** - * Centers an icon in the split staging area, accounting for insets. - * @param out The icon that needs to be centered. - * @param onScreenRectCenterX The x-center of the on-screen staging area (most of the Rect is - * offscreen). - * @param onScreenRectCenterY The y-center of the on-screen staging area (most of the Rect is - * offscreen). - * @param fullscreenScaleX A x-scaling factor used to convert coordinates back into pixels. - * @param fullscreenScaleY A y-scaling factor used to convert coordinates back into pixels. - * @param drawableWidth The icon's drawable (final) width. - * @param drawableHeight The icon's drawable (final) height. - * @param dp The device profile, used to report rotation and hardware insets. - * @param stagePosition 0 if the staging area is pinned to top/left, 1 for bottom/right. - */ - void updateSplitIconParams(View out, float onScreenRectCenterX, - float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY, - int drawableWidth, int drawableHeight, DeviceProfile dp, - @StagePosition int stagePosition); - - /** - * Sets positioning and rotation for a SplitInstructionsView. - * @param out The SplitInstructionsView that needs to be positioned. - * @param dp The device profile, used to report rotation and device type. - * @param splitInstructionsHeight The SplitInstructionView's height. - * @param splitInstructionsWidth The SplitInstructionView's width. - */ - void setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight, - int splitInstructionsWidth); - - /** - * @param splitDividerSize height of split screen drag handle in portrait, width in landscape - * @param stagePosition the split position option (top/left, bottom/right) of the first - * task selected for entering split - * @param out1 the bounds for where the first selected app will be - * @param out2 the bounds for where the second selected app will be, complimentary to - * {@param out1} based on {@param initialSplitOption} - */ - void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp, - @StagePosition int stagePosition, Rect out1, Rect out2); - - int getDefaultSplitPosition(DeviceProfile deviceProfile); - - /** - * @param outRect This is expected to be the rect that has the dimensions for a non-split, - * fullscreen task in overview. This will directly be modified. - * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize - * outRect for - */ - void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect, SplitBounds splitInfo, - @SplitConfigurationOptions.StagePosition int desiredStagePosition); - - void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, - int parentWidth, int parentHeight, - SplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl); - - // Overview TaskMenuView methods - void setTaskIconParams(FrameLayout.LayoutParams iconParams, - int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl); - void setIconAppChipMenuParams(View iconAppChipMenuView, FrameLayout.LayoutParams iconMenuParams, - int iconMenuMargin, int thumbnailTopMargin); - void setSplitIconParams(View primaryIconView, View secondaryIconView, - int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight, - int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl, - DeviceProfile deviceProfile, SplitBounds splitConfig); - - /* - * The following two methods try to center the TaskMenuView in landscape by finding the center - * of the thumbnail view and then subtracting half of the taskMenu width. In this case, the - * taskMenu width is the same size as the thumbnail width (what got set below in - * getTaskMenuWidth()), so we directly use that in the calculations. - */ - float getTaskMenuX(float x, View thumbnailView, DeviceProfile deviceProfile, - float taskInsetMargin, View taskViewIcon); - float getTaskMenuY(float y, View thumbnailView, int stagePosition, - View taskMenuView, float taskInsetMargin, View taskViewIcon); - int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile, - @StagePosition int stagePosition); - /** - * Sets linear layout orientation for {@link com.android.launcher3.popup.SystemShortcut} items - * inside task menu view. - */ - void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile, - LinearLayout taskMenuLayout, int dividerSpacing, - ShapeDrawable dividerDrawable); - /** - * Sets layout param attributes for {@link com.android.launcher3.popup.SystemShortcut} child - * views inside task menu view. - */ - void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp, - LinearLayout viewGroup, DeviceProfile deviceProfile); - - /** - * Calculates the position where a Digital Wellbeing Banner should be placed on its parent - * TaskView. - * @return A Pair of Floats representing the proper x and y translations. - */ - Pair getDwbLayoutTranslations(int taskViewWidth, - int taskViewHeight, SplitBounds splitBounds, DeviceProfile deviceProfile, - View[] thumbnailViews, int desiredTaskId, View banner); - - // The following are only used by TaskViewTouchHandler. - /** @return Either VERTICAL or HORIZONTAL. */ - SingleAxisSwipeDetector.Direction getUpDownSwipeDirection(); - /** @return Given {@link #getUpDownSwipeDirection()}, whether POSITIVE or NEGATIVE is up. */ - int getUpDirection(boolean isRtl); - /** @return Whether the displacement is going towards the top of the screen. */ - boolean isGoingUp(float displacement, boolean isRtl); - /** @return Either 1 or -1, a factor to multiply by so the animation goes the correct way. */ - int getTaskDragDisplacementFactor(boolean isRtl); - - /** - * Maps the velocity from the coordinate plane of the foreground app to that - * of Launcher's (which now will always be portrait) - */ - void adjustFloatingIconStartVelocity(PointF velocity); - - /** - * Ensures that outStartRect left bound is within the DeviceProfile's visual boundaries - * @param outStartRect The start rect that will directly be modified - */ - void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile); - - /** - * Determine the target translation for animating the FloatingTaskView out. This value could - * either be an x-coordinate or a y-coordinate, depending on which way the FloatingTaskView was - * docked. - * - * @param floatingTask The FloatingTaskView. - * @param onScreenRect The current on-screen dimensions of the FloatingTaskView. - * @param stagePosition STAGE_POSITION_TOP_OR_LEFT or STAGE_POSITION_BOTTOM_OR_RIGHT. - * @param dp The device profile. - * @return A float. When an animation translates the FloatingTaskView to this position, it will - * appear to tuck away off the edge of the screen. - */ - float getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect, - @StagePosition int stagePosition, DeviceProfile dp); - - /** - * Sets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be - * either x or y), depending on how the view is oriented. - * - * @param floatingTask The FloatingTaskView to be translated. - * @param translation The target translation value. - * @param dp The current device profile. - */ - void setFloatingTaskPrimaryTranslation(View floatingTask, float translation, DeviceProfile dp); - - /** - * Gets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be - * either x or y), depending on how the view is oriented. - * - * @param floatingTask The FloatingTaskView in question. - * @param dp The current device profile. - * @return The current translation value. - */ - Float getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp); - class ChildBounds { public final int primaryDimension; @@ -279,8 +73,8 @@ public interface PagedOrientationHandler { public final int childPrimaryEnd; public final int childSecondaryEnd; - ChildBounds(int primaryDimension, int secondaryDimension, int childPrimaryEnd, - int childSecondaryEnd) { + public ChildBounds(int primaryDimension, int secondaryDimension, int childPrimaryEnd, + int childSecondaryEnd) { this.primaryDimension = primaryDimension; this.secondaryDimension = secondaryDimension; this.childPrimaryEnd = childPrimaryEnd;