From 715e25adf43c14fdef9579c2c04d0f0bd91c5fbc Mon Sep 17 00:00:00 2001 From: Jordan Silva Date: Tue, 30 Jan 2024 18:02:27 +0000 Subject: [PATCH] Refactoring PagedOrientationHandler to extract functions from to quickstep This CL extracts RecentsView methods from PagedOrientationHandler to RecentsPagedOrientationHandler. It will allow to have quickstep specific components in the newer interface, like IconAppChipView. Bug: 320633351 Flag: N/A Test: atest NexusLauncherTests Test: atest TaplTestsSplitscreen Test: atest TaplTestsQuickstep Change-Id: Ie7de23bddccbdb8eac93eff66a5d929f5bf0ee3a --- .../RecentsViewStateController.java | 4 +- .../TaskViewTouchController.java | 14 +- .../quickstep/BaseActivityInterface.java | 3 +- .../quickstep/FallbackActivityInterface.java | 4 +- .../quickstep/LauncherActivityInterface.java | 4 +- .../QuickstepTestInformationHandler.java | 6 +- .../quickstep/SwipeUpAnimationLogic.java | 3 +- .../quickstep/TaskShortcutFactory.java | 4 +- .../LandscapePagedViewHandler.java | 22 +- .../PortraitPagedViewHandler.java | 125 +-------- .../RecentsPagedOrientationHandler.java | 241 ++++++++++++++++++ .../SeascapePagedViewHandler.java | 20 +- .../AnimatorControllerWithResistance.java | 4 +- .../android/quickstep/util/LayoutUtils.java | 4 +- .../quickstep/util/RecentsOrientedState.java | 14 +- .../quickstep/views/ClearAllButton.java | 14 +- .../views/DigitalWellBeingToast.java | 4 +- .../quickstep/views/FloatingTaskView.java | 6 +- .../quickstep/views/IconAppChipView.java | 5 +- .../com/android/quickstep/views/IconView.java | 5 +- .../android/quickstep/views/RecentsView.java | 168 ++++++------ .../android/quickstep/views/TaskMenuView.java | 5 +- .../quickstep/views/TaskThumbnailView.java | 4 +- .../com/android/quickstep/views/TaskView.java | 8 +- src/com/android/launcher3/PagedView.java | 11 +- .../touch/DefaultPagedViewHandler.java | 128 ++++++++++ .../touch/PagedOrientationHandler.java | 212 +-------------- 27 files changed, 568 insertions(+), 474 deletions(-) rename {src/com/android/launcher3/touch => quickstep/src/com/android/quickstep/orientation}/LandscapePagedViewHandler.java (97%) rename {src/com/android/launcher3/touch => quickstep/src/com/android/quickstep/orientation}/PortraitPagedViewHandler.java (90%) create mode 100644 quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java rename {src/com/android/launcher3/touch => quickstep/src/com/android/quickstep/orientation}/SeascapePagedViewHandler.java (96%) create mode 100644 src/com/android/launcher3/touch/DefaultPagedViewHandler.java 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;