Loading quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +11 −5 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowInsets; import android.view.animation.Interpolator; import android.widget.Toast; Loading Loading @@ -139,6 +140,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, private final Handler mHandler = new Handler(); // Callbacks to be made once the recents animation starts private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>(); private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll; protected RecentsAnimationController mRecentsAnimationController; protected RecentsAnimationTargets mRecentsAnimationTargets; protected T mActivity; Loading Loading @@ -1368,6 +1371,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, private void invalidateHandlerWithLauncher() { endLauncherTransitionController(); mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener); mRecentsView.onGestureAnimationEnd(); resetLauncherListeners(); } Loading Loading @@ -1562,17 +1566,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, mRecentsAnimationTargets.addReleaseCheck(applier)); }); mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { if (moveWindowWithRecentsScroll()) { updateFinalShift(); } }); mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener); runOnRecentsAnimationStart(() -> mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController, mRecentsAnimationTargets)); mRecentsViewScrollLinked = true; } private void onRecentsViewScroll() { if (moveWindowWithRecentsScroll()) { updateFinalShift(); } } protected void startNewTask(Consumer<Boolean> resultCallback) { // Launch the task user scrolled to (mRecentsView.getNextPage()). if (!mCanceled) { Loading quickstep/src/com/android/quickstep/views/RecentsView.java +133 −25 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; import static com.android.launcher3.statehandlers.DepthController.DEPTH; import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; Loading Loading @@ -88,11 +89,13 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.Interpolator; import android.widget.FrameLayout; import android.widget.ListView; import android.widget.OverScroller; import androidx.annotation.Nullable; import androidx.annotation.UiThread; Loading @@ -116,14 +119,15 @@ import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.OverScroll; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.OverScroller; import com.android.launcher3.util.ResourceBasedOverride.Overrides; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.Themes; import com.android.launcher3.util.TranslateEdgeEffect; import com.android.launcher3.util.ViewPool; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseActivityInterface; Loading Loading @@ -157,6 +161,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.pip.IPipAnimationListener; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; /** Loading Loading @@ -296,6 +301,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } }; // OverScroll constants private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270; protected final RecentsOrientedState mOrientationState; protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy; protected RecentsAnimationController mRecentsAnimationController; Loading @@ -314,6 +322,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T protected final Rect mTempRect = new Rect(); protected final RectF mTempRectF = new RectF(); private final PointF mTempPointF = new PointF(); private final float[] mTempFloat = new float[1]; private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>(); private float mFullscreenScale; private static final int DISMISS_TASK_DURATION = 300; Loading Loading @@ -360,6 +370,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T IntSet mTopIdSet = new IntSet(); private int mOverScrollShift = 0; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. */ Loading Loading @@ -583,6 +596,72 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return mIsRtl; } @Override protected void initEdgeEffect() { mEdgeGlowLeft = new TranslateEdgeEffect(getContext()); mEdgeGlowRight = new TranslateEdgeEffect(getContext()); } @Override protected void drawEdgeEffect(Canvas canvas) { // Do not draw edge effect } @Override protected void dispatchDraw(Canvas canvas) { // Draw overscroll if (mAllowOverScroll && (!mEdgeGlowRight.isFinished() || !mEdgeGlowLeft.isFinished())) { final int restoreCount = canvas.save(); final int width = getWidth(); final int height = getHeight(); int primarySize = mOrientationHandler.getPrimaryValue(width, height); int secondarySize = mOrientationHandler.getSecondaryValue(width, height); float effectiveShift = 0; if (!mEdgeGlowLeft.isFinished()) { mEdgeGlowLeft.setSize(secondarySize, primarySize); if (((TranslateEdgeEffect) mEdgeGlowLeft).getTranslationShift(mTempFloat)) { effectiveShift = mTempFloat[0]; postInvalidateOnAnimation(); } } if (!mEdgeGlowRight.isFinished()) { mEdgeGlowRight.setSize(secondarySize, primarySize); if (((TranslateEdgeEffect) mEdgeGlowRight).getTranslationShift(mTempFloat)) { effectiveShift -= mTempFloat[0]; postInvalidateOnAnimation(); } } int scroll = OverScroll.dampedScroll(effectiveShift * primarySize, primarySize); mOrientationHandler.set(canvas, CANVAS_TRANSLATE, scroll); if (mOverScrollShift != scroll) { mOverScrollShift = scroll; dispatchScrollChanged(); } super.dispatchDraw(canvas); canvas.restoreToCount(restoreCount); } else { if (mOverScrollShift != 0) { mOverScrollShift = 0; dispatchScrollChanged(); } super.dispatchDraw(canvas); } if (LIVE_TILE.get() && mEnableDrawingLiveTile && mLiveTileParams.getTargetSet() != null) { redrawLiveTile(); } } /** * Returns the view shift due to overscroll */ public int getOverScrollShift() { return mOverScrollShift; } @Override public Task onTaskThumbnailChanged(int taskId, ThumbnailData thumbnailData) { if (mHandleTaskStackChanges) { Loading Loading @@ -936,8 +1015,30 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } @Override protected boolean snapToPageInFreeScroll() { return !showAsGrid(); protected void onNotSnappingToPageInFreeScroll() { int finalPos = mScroller.getFinalX(); if (!showAsGrid() && finalPos > mMinScroll && finalPos < mMaxScroll) { int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1); int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0); // If scrolling ends in the half of the added space that is closer to // the end, settle to the end. Otherwise snap to the nearest page. // If flinging past one of the ends, don't change the velocity as it // will get stopped at the end anyway. int pageSnapped = finalPos < (firstPageScroll + mMinScroll) / 2 ? mMinScroll : finalPos > (lastPageScroll + mMaxScroll) / 2 ? mMaxScroll : getScrollForPage(mNextPage); mScroller.setFinalX(pageSnapped); // Ensure the scroll/snap doesn't happen too fast; int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION - mScroller.getDuration(); if (extraScrollDuration > 0) { mScroller.extendDuration(extraScrollDuration); } } } @Override Loading Loading @@ -1267,12 +1368,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T // Update the high res thumbnail loader state mModel.getThumbnailCache().getHighResLoadingState().setFlingingFast(isFlingingFast); mLiveTileTaskViewSimulator.setScroll(getScrollOffset()); if (LIVE_TILE.get() && mEnableDrawingLiveTile && mLiveTileParams.getTargetSet() != null) { redrawLiveTile(); } return scrolling; } Loading Loading @@ -1571,7 +1666,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T updateOrientationHandler(); } setOnScrollChangeListener(null); setEnableFreeScroll(true); setEnableDrawingLiveTile(true); if (!LIVE_TILE.get()) { Loading Loading @@ -3207,13 +3301,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return mClearAllButton; } @Override protected boolean onOverscroll(int amount) { // overscroll should only be accepted on -1 direction (for clear all button) if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false; return super.onOverscroll(amount); } /** * @return How many pixels the running task is offset on the currently laid out dominant axis. */ Loading @@ -3228,14 +3315,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T if (pageIndex == -1) { return 0; } // Unbound the scroll (due to overscroll) if the adjacent tasks are offset away from it. // This allows the page to move freely, given there's no visual indication why it shouldn't. int boundedScroll = mOrientationHandler.getPrimaryScroll(this); int unboundedScroll = getUnboundedScroll(); float unboundedProgress = mAdjacentPageOffset; int scroll = Math.round(unboundedScroll * unboundedProgress + boundedScroll * (1 - unboundedProgress)); return getScrollForPage(pageIndex) - scroll; return getScrollForPage(pageIndex) - mOrientationHandler.getPrimaryScroll(this) + getOverScrollShift(); } /** Loading Loading @@ -3421,6 +3502,33 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T void onEmptyMessageUpdated(boolean isEmpty); } /** * Adds a listener for scroll changes */ public void addOnScrollChangedListener(OnScrollChangedListener listener) { mScrollListeners.add(listener); } /** * Removes a previously added scroll change listener */ public void removeOnScrollChangedListener(OnScrollChangedListener listener) { mScrollListeners.remove(listener); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); dispatchScrollChanged(); } private void dispatchScrollChanged() { mLiveTileTaskViewSimulator.setScroll(getScrollOffset()); for (int i = mScrollListeners.size() - 1; i >= 0; i--) { mScrollListeners.get(i).onScrollChanged(); } } private static class PinnedStackAnimationListener<T extends BaseActivity> extends IPipAnimationListener.Stub { private T mActivity; Loading quickstep/src/com/android/quickstep/views/TaskMenuView.java +9 −7 Original line number Diff line number Diff line Loading @@ -121,7 +121,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange }; } private void setPosition(float x, float y) { private void setPosition(float x, float y, int overscrollShift) { PagedOrientationHandler pagedOrientationHandler = mTaskView.getPagedOrientationHandler(); int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx; float adjustedY = y + taskTopMargin; Loading @@ -136,8 +136,9 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange setPivotY(0); } setRotation(pagedOrientationHandler.getDegreesRotated()); setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail())); setY(pagedOrientationHandler.getTaskMenuY(adjustedY, mTaskView.getThumbnail())); setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail(), overscrollShift)); setY(pagedOrientationHandler.getTaskMenuY( adjustedY, mTaskView.getThumbnail(), overscrollShift)); } public void onRotationChanged() { Loading Loading @@ -169,14 +170,15 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange return false; } post(this::animateOpen); mActivity.getRootView().getViewTreeObserver().addOnScrollChangedListener(this); ((RecentsView) mActivity.getOverviewPanel()).addOnScrollChangedListener(this); return true; } @Override public void onScrollChanged() { RecentsView rv = mTaskView.getRecentsView(); setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY()); setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY(), rv.getOverScrollShift()); } /** @return true if successfully able to populate task view menu, false otherwise */ Loading Loading @@ -236,7 +238,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange .mOrientationState.isRecentsActivityRotationAllowed(); mOptionLayout.setOrientation(orientationHandler .getTaskMenuLayoutOrientation(canActivityRotate, mOptionLayout)); setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top); setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0); } private void animateOpen() { Loading Loading @@ -282,7 +284,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange private void closeComplete() { mIsOpen = false; mActivity.getDragLayer().removeView(this); mActivity.getRootView().getViewTreeObserver().removeOnScrollChangedListener(this); ((RecentsView) mActivity.getOverviewPanel()).removeOnScrollChangedListener(this); } private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() { Loading src/com/android/launcher3/PagedView.java +153 −250 File changed.Preview size limit exceeded, changes collapsed. Show changes src/com/android/launcher3/Workspace.java +13 −73 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_ICONS_CAN_BE_DR import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_INACCESSIBLE; import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; Loading Loading @@ -96,10 +95,12 @@ import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.WorkspaceTouchListener; import com.android.launcher3.util.EdgeEffectCompat; import com.android.launcher3.util.Executors; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSparseArrayMap; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.OverlayEdgeEffect; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.WallpaperOffsetInterpolator; Loading Loading @@ -245,10 +246,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> private float mTransitionProgress; // State related to Launcher Overlay LauncherOverlay mLauncherOverlay; boolean mScrollInteractionBegan; boolean mStartedSendingScrollEvents; float mLastOverlayScroll = 0; private OverlayEdgeEffect mOverlayEdgeEffect; boolean mOverlayShown = false; private Runnable mOnOverlayHiddenCallback; Loading Loading @@ -945,47 +943,25 @@ public class Workspace extends PagedView<WorkspacePageIndicator> } } protected void onScrollInteractionBegin() { super.onScrollInteractionBegin(); mScrollInteractionBegan = true; } protected void onScrollInteractionEnd() { super.onScrollInteractionEnd(); mScrollInteractionBegan = false; if (mStartedSendingScrollEvents) { mStartedSendingScrollEvents = false; mLauncherOverlay.onScrollInteractionEnd(); } } public void setLauncherOverlay(LauncherOverlay overlay) { mLauncherOverlay = overlay; // A new overlay has been set. Reset event tracking mStartedSendingScrollEvents = false; mOverlayEdgeEffect = overlay == null ? null : new OverlayEdgeEffect(getContext(), overlay); EdgeEffectCompat newEffect = overlay == null ? new EdgeEffectCompat(getContext()) : mOverlayEdgeEffect; if (mIsRtl) { mEdgeGlowRight = newEffect; } else { mEdgeGlowLeft = newEffect; } onOverlayScrollChanged(0); } public boolean hasOverlay() { return mLauncherOverlay != null; } private boolean isScrollingOverlay() { return mLauncherOverlay != null && ((mIsRtl && getUnboundedScroll() > mMaxScroll) || (!mIsRtl && getUnboundedScroll() < mMinScroll)); return mOverlayEdgeEffect != null; } @Override protected void snapToDestination() { // If we're overscrolling the overlay, we make sure to immediately reset the PagedView // to it's baseline position instead of letting the overscroll settle. The overlay handles // it's own settling, and every gesture to the overlay should be self-contained and start // from 0, so we zero it out here. if (isScrollingOverlay()) { // We reset mWasInOverscroll so that PagedView doesn't zero out the overscroll // interaction when we call snapToPageImmediately. mWasInOverscroll = false; if (mOverlayEdgeEffect != null && !mOverlayEdgeEffect.isFinished()) { snapToPageImmediately(0); } else { super.snapToDestination(); Loading Loading @@ -1017,38 +993,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator> } } @Override protected void overScroll(int amount) { boolean shouldScrollOverlay = mLauncherOverlay != null && !mScroller.isSpringing() && ((amount <= 0 && !mIsRtl) || (amount >= 0 && mIsRtl)); boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlayScroll != 0 && ((amount >= 0 && !mIsRtl) || (amount <= 0 && mIsRtl)); if (shouldScrollOverlay) { if (!mStartedSendingScrollEvents && mScrollInteractionBegan) { mStartedSendingScrollEvents = true; mLauncherOverlay.onScrollInteractionBegin(); } mLastOverlayScroll = Math.abs(((float) amount) / getMeasuredWidth()); mLauncherOverlay.onScrollChange(mLastOverlayScroll, mIsRtl); } else { dampedOverScroll(amount); } if (shouldZeroOverlay) { mLauncherOverlay.onScrollChange(0, mIsRtl); } } @Override protected boolean onOverscroll(int amount) { // Enforce overscroll on -1 direction if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false; return super.onOverscroll(amount); } @Override protected boolean shouldFlingForVelocity(int velocityX) { // When the overlay is moving, the fling or settle transition is controlled by the overlay. Loading Loading @@ -1377,10 +1321,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator> mOutlineProvider = outlineProvider; } public void snapToPageFromOverView(int whichPage) { snapToPage(whichPage, OVERVIEW.getTransitionDuration(mLauncher), Interpolators.ZOOM_IN); } private void onStartStateTransition(LauncherState state) { mIsSwitchingState = true; mTransitionProgress = 0; Loading Loading
quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +11 −5 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowInsets; import android.view.animation.Interpolator; import android.widget.Toast; Loading Loading @@ -139,6 +140,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, private final Handler mHandler = new Handler(); // Callbacks to be made once the recents animation starts private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>(); private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll; protected RecentsAnimationController mRecentsAnimationController; protected RecentsAnimationTargets mRecentsAnimationTargets; protected T mActivity; Loading Loading @@ -1368,6 +1371,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, private void invalidateHandlerWithLauncher() { endLauncherTransitionController(); mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener); mRecentsView.onGestureAnimationEnd(); resetLauncherListeners(); } Loading Loading @@ -1562,17 +1566,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, mRecentsAnimationTargets.addReleaseCheck(applier)); }); mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { if (moveWindowWithRecentsScroll()) { updateFinalShift(); } }); mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener); runOnRecentsAnimationStart(() -> mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController, mRecentsAnimationTargets)); mRecentsViewScrollLinked = true; } private void onRecentsViewScroll() { if (moveWindowWithRecentsScroll()) { updateFinalShift(); } } protected void startNewTask(Consumer<Boolean> resultCallback) { // Launch the task user scrolled to (mRecentsView.getNextPage()). if (!mCanceled) { Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +133 −25 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; import static com.android.launcher3.statehandlers.DepthController.DEPTH; import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; Loading Loading @@ -88,11 +89,13 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.Interpolator; import android.widget.FrameLayout; import android.widget.ListView; import android.widget.OverScroller; import androidx.annotation.Nullable; import androidx.annotation.UiThread; Loading @@ -116,14 +119,15 @@ import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.OverScroll; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.OverScroller; import com.android.launcher3.util.ResourceBasedOverride.Overrides; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.Themes; import com.android.launcher3.util.TranslateEdgeEffect; import com.android.launcher3.util.ViewPool; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseActivityInterface; Loading Loading @@ -157,6 +161,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.pip.IPipAnimationListener; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; /** Loading Loading @@ -296,6 +301,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } }; // OverScroll constants private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270; protected final RecentsOrientedState mOrientationState; protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy; protected RecentsAnimationController mRecentsAnimationController; Loading @@ -314,6 +322,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T protected final Rect mTempRect = new Rect(); protected final RectF mTempRectF = new RectF(); private final PointF mTempPointF = new PointF(); private final float[] mTempFloat = new float[1]; private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>(); private float mFullscreenScale; private static final int DISMISS_TASK_DURATION = 300; Loading Loading @@ -360,6 +370,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T IntSet mTopIdSet = new IntSet(); private int mOverScrollShift = 0; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. */ Loading Loading @@ -583,6 +596,72 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return mIsRtl; } @Override protected void initEdgeEffect() { mEdgeGlowLeft = new TranslateEdgeEffect(getContext()); mEdgeGlowRight = new TranslateEdgeEffect(getContext()); } @Override protected void drawEdgeEffect(Canvas canvas) { // Do not draw edge effect } @Override protected void dispatchDraw(Canvas canvas) { // Draw overscroll if (mAllowOverScroll && (!mEdgeGlowRight.isFinished() || !mEdgeGlowLeft.isFinished())) { final int restoreCount = canvas.save(); final int width = getWidth(); final int height = getHeight(); int primarySize = mOrientationHandler.getPrimaryValue(width, height); int secondarySize = mOrientationHandler.getSecondaryValue(width, height); float effectiveShift = 0; if (!mEdgeGlowLeft.isFinished()) { mEdgeGlowLeft.setSize(secondarySize, primarySize); if (((TranslateEdgeEffect) mEdgeGlowLeft).getTranslationShift(mTempFloat)) { effectiveShift = mTempFloat[0]; postInvalidateOnAnimation(); } } if (!mEdgeGlowRight.isFinished()) { mEdgeGlowRight.setSize(secondarySize, primarySize); if (((TranslateEdgeEffect) mEdgeGlowRight).getTranslationShift(mTempFloat)) { effectiveShift -= mTempFloat[0]; postInvalidateOnAnimation(); } } int scroll = OverScroll.dampedScroll(effectiveShift * primarySize, primarySize); mOrientationHandler.set(canvas, CANVAS_TRANSLATE, scroll); if (mOverScrollShift != scroll) { mOverScrollShift = scroll; dispatchScrollChanged(); } super.dispatchDraw(canvas); canvas.restoreToCount(restoreCount); } else { if (mOverScrollShift != 0) { mOverScrollShift = 0; dispatchScrollChanged(); } super.dispatchDraw(canvas); } if (LIVE_TILE.get() && mEnableDrawingLiveTile && mLiveTileParams.getTargetSet() != null) { redrawLiveTile(); } } /** * Returns the view shift due to overscroll */ public int getOverScrollShift() { return mOverScrollShift; } @Override public Task onTaskThumbnailChanged(int taskId, ThumbnailData thumbnailData) { if (mHandleTaskStackChanges) { Loading Loading @@ -936,8 +1015,30 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } @Override protected boolean snapToPageInFreeScroll() { return !showAsGrid(); protected void onNotSnappingToPageInFreeScroll() { int finalPos = mScroller.getFinalX(); if (!showAsGrid() && finalPos > mMinScroll && finalPos < mMaxScroll) { int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1); int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0); // If scrolling ends in the half of the added space that is closer to // the end, settle to the end. Otherwise snap to the nearest page. // If flinging past one of the ends, don't change the velocity as it // will get stopped at the end anyway. int pageSnapped = finalPos < (firstPageScroll + mMinScroll) / 2 ? mMinScroll : finalPos > (lastPageScroll + mMaxScroll) / 2 ? mMaxScroll : getScrollForPage(mNextPage); mScroller.setFinalX(pageSnapped); // Ensure the scroll/snap doesn't happen too fast; int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION - mScroller.getDuration(); if (extraScrollDuration > 0) { mScroller.extendDuration(extraScrollDuration); } } } @Override Loading Loading @@ -1267,12 +1368,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T // Update the high res thumbnail loader state mModel.getThumbnailCache().getHighResLoadingState().setFlingingFast(isFlingingFast); mLiveTileTaskViewSimulator.setScroll(getScrollOffset()); if (LIVE_TILE.get() && mEnableDrawingLiveTile && mLiveTileParams.getTargetSet() != null) { redrawLiveTile(); } return scrolling; } Loading Loading @@ -1571,7 +1666,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T updateOrientationHandler(); } setOnScrollChangeListener(null); setEnableFreeScroll(true); setEnableDrawingLiveTile(true); if (!LIVE_TILE.get()) { Loading Loading @@ -3207,13 +3301,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return mClearAllButton; } @Override protected boolean onOverscroll(int amount) { // overscroll should only be accepted on -1 direction (for clear all button) if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false; return super.onOverscroll(amount); } /** * @return How many pixels the running task is offset on the currently laid out dominant axis. */ Loading @@ -3228,14 +3315,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T if (pageIndex == -1) { return 0; } // Unbound the scroll (due to overscroll) if the adjacent tasks are offset away from it. // This allows the page to move freely, given there's no visual indication why it shouldn't. int boundedScroll = mOrientationHandler.getPrimaryScroll(this); int unboundedScroll = getUnboundedScroll(); float unboundedProgress = mAdjacentPageOffset; int scroll = Math.round(unboundedScroll * unboundedProgress + boundedScroll * (1 - unboundedProgress)); return getScrollForPage(pageIndex) - scroll; return getScrollForPage(pageIndex) - mOrientationHandler.getPrimaryScroll(this) + getOverScrollShift(); } /** Loading Loading @@ -3421,6 +3502,33 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T void onEmptyMessageUpdated(boolean isEmpty); } /** * Adds a listener for scroll changes */ public void addOnScrollChangedListener(OnScrollChangedListener listener) { mScrollListeners.add(listener); } /** * Removes a previously added scroll change listener */ public void removeOnScrollChangedListener(OnScrollChangedListener listener) { mScrollListeners.remove(listener); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); dispatchScrollChanged(); } private void dispatchScrollChanged() { mLiveTileTaskViewSimulator.setScroll(getScrollOffset()); for (int i = mScrollListeners.size() - 1; i >= 0; i--) { mScrollListeners.get(i).onScrollChanged(); } } private static class PinnedStackAnimationListener<T extends BaseActivity> extends IPipAnimationListener.Stub { private T mActivity; Loading
quickstep/src/com/android/quickstep/views/TaskMenuView.java +9 −7 Original line number Diff line number Diff line Loading @@ -121,7 +121,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange }; } private void setPosition(float x, float y) { private void setPosition(float x, float y, int overscrollShift) { PagedOrientationHandler pagedOrientationHandler = mTaskView.getPagedOrientationHandler(); int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx; float adjustedY = y + taskTopMargin; Loading @@ -136,8 +136,9 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange setPivotY(0); } setRotation(pagedOrientationHandler.getDegreesRotated()); setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail())); setY(pagedOrientationHandler.getTaskMenuY(adjustedY, mTaskView.getThumbnail())); setX(pagedOrientationHandler.getTaskMenuX(x, mTaskView.getThumbnail(), overscrollShift)); setY(pagedOrientationHandler.getTaskMenuY( adjustedY, mTaskView.getThumbnail(), overscrollShift)); } public void onRotationChanged() { Loading Loading @@ -169,14 +170,15 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange return false; } post(this::animateOpen); mActivity.getRootView().getViewTreeObserver().addOnScrollChangedListener(this); ((RecentsView) mActivity.getOverviewPanel()).addOnScrollChangedListener(this); return true; } @Override public void onScrollChanged() { RecentsView rv = mTaskView.getRecentsView(); setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY()); setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY(), rv.getOverScrollShift()); } /** @return true if successfully able to populate task view menu, false otherwise */ Loading Loading @@ -236,7 +238,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange .mOrientationState.isRecentsActivityRotationAllowed(); mOptionLayout.setOrientation(orientationHandler .getTaskMenuLayoutOrientation(canActivityRotate, mOptionLayout)); setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top); setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0); } private void animateOpen() { Loading Loading @@ -282,7 +284,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange private void closeComplete() { mIsOpen = false; mActivity.getDragLayer().removeView(this); mActivity.getRootView().getViewTreeObserver().removeOnScrollChangedListener(this); ((RecentsView) mActivity.getOverviewPanel()).removeOnScrollChangedListener(this); } private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() { Loading
src/com/android/launcher3/PagedView.java +153 −250 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/com/android/launcher3/Workspace.java +13 −73 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_ICONS_CAN_BE_DR import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_INACCESSIBLE; import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; Loading Loading @@ -96,10 +95,12 @@ import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.WorkspaceTouchListener; import com.android.launcher3.util.EdgeEffectCompat; import com.android.launcher3.util.Executors; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSparseArrayMap; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.OverlayEdgeEffect; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.WallpaperOffsetInterpolator; Loading Loading @@ -245,10 +246,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> private float mTransitionProgress; // State related to Launcher Overlay LauncherOverlay mLauncherOverlay; boolean mScrollInteractionBegan; boolean mStartedSendingScrollEvents; float mLastOverlayScroll = 0; private OverlayEdgeEffect mOverlayEdgeEffect; boolean mOverlayShown = false; private Runnable mOnOverlayHiddenCallback; Loading Loading @@ -945,47 +943,25 @@ public class Workspace extends PagedView<WorkspacePageIndicator> } } protected void onScrollInteractionBegin() { super.onScrollInteractionBegin(); mScrollInteractionBegan = true; } protected void onScrollInteractionEnd() { super.onScrollInteractionEnd(); mScrollInteractionBegan = false; if (mStartedSendingScrollEvents) { mStartedSendingScrollEvents = false; mLauncherOverlay.onScrollInteractionEnd(); } } public void setLauncherOverlay(LauncherOverlay overlay) { mLauncherOverlay = overlay; // A new overlay has been set. Reset event tracking mStartedSendingScrollEvents = false; mOverlayEdgeEffect = overlay == null ? null : new OverlayEdgeEffect(getContext(), overlay); EdgeEffectCompat newEffect = overlay == null ? new EdgeEffectCompat(getContext()) : mOverlayEdgeEffect; if (mIsRtl) { mEdgeGlowRight = newEffect; } else { mEdgeGlowLeft = newEffect; } onOverlayScrollChanged(0); } public boolean hasOverlay() { return mLauncherOverlay != null; } private boolean isScrollingOverlay() { return mLauncherOverlay != null && ((mIsRtl && getUnboundedScroll() > mMaxScroll) || (!mIsRtl && getUnboundedScroll() < mMinScroll)); return mOverlayEdgeEffect != null; } @Override protected void snapToDestination() { // If we're overscrolling the overlay, we make sure to immediately reset the PagedView // to it's baseline position instead of letting the overscroll settle. The overlay handles // it's own settling, and every gesture to the overlay should be self-contained and start // from 0, so we zero it out here. if (isScrollingOverlay()) { // We reset mWasInOverscroll so that PagedView doesn't zero out the overscroll // interaction when we call snapToPageImmediately. mWasInOverscroll = false; if (mOverlayEdgeEffect != null && !mOverlayEdgeEffect.isFinished()) { snapToPageImmediately(0); } else { super.snapToDestination(); Loading Loading @@ -1017,38 +993,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator> } } @Override protected void overScroll(int amount) { boolean shouldScrollOverlay = mLauncherOverlay != null && !mScroller.isSpringing() && ((amount <= 0 && !mIsRtl) || (amount >= 0 && mIsRtl)); boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlayScroll != 0 && ((amount >= 0 && !mIsRtl) || (amount <= 0 && mIsRtl)); if (shouldScrollOverlay) { if (!mStartedSendingScrollEvents && mScrollInteractionBegan) { mStartedSendingScrollEvents = true; mLauncherOverlay.onScrollInteractionBegin(); } mLastOverlayScroll = Math.abs(((float) amount) / getMeasuredWidth()); mLauncherOverlay.onScrollChange(mLastOverlayScroll, mIsRtl); } else { dampedOverScroll(amount); } if (shouldZeroOverlay) { mLauncherOverlay.onScrollChange(0, mIsRtl); } } @Override protected boolean onOverscroll(int amount) { // Enforce overscroll on -1 direction if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false; return super.onOverscroll(amount); } @Override protected boolean shouldFlingForVelocity(int velocityX) { // When the overlay is moving, the fling or settle transition is controlled by the overlay. Loading Loading @@ -1377,10 +1321,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator> mOutlineProvider = outlineProvider; } public void snapToPageFromOverView(int whichPage) { snapToPage(whichPage, OVERVIEW.getTransitionDuration(mLauncher), Interpolators.ZOOM_IN); } private void onStartStateTransition(LauncherState state) { mIsSwitchingState = true; mTransitionProgress = 0; Loading