diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index eed67b62c2..36e642075f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -26,6 +26,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseQuickstepLauncher; @@ -74,6 +75,8 @@ import java.util.function.Supplier; private int mState; private LauncherState mLauncherState = LauncherState.NORMAL; + private @Nullable TaskBarRecentsAnimationListener mTaskBarRecentsAnimationListener; + private boolean mIsAnimatingToLauncherViaGesture; private boolean mIsAnimatingToLauncherViaResume; @@ -163,12 +166,11 @@ import java.util.function.Supplier; animatorSet.play(stashController.applyStateWithoutStart(duration)); animatorSet.play(applyState(duration, false)); - TaskBarRecentsAnimationListener listener = new TaskBarRecentsAnimationListener(callbacks); - callbacks.addListener(listener); + mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks); + callbacks.addListener(mTaskBarRecentsAnimationListener); RecentsView recentsView = mLauncher.getOverviewPanel(); recentsView.setTaskLaunchListener(() -> { - listener.endGestureStateOverride(true); - callbacks.removeListener(listener); + mTaskBarRecentsAnimationListener.endGestureStateOverride(true); }); return animatorSet; } @@ -257,7 +259,10 @@ import java.util.function.Supplier; if (hasAnyFlag(changedFlags, FLAG_RESUMED) || launcherStateChangedDuringAnimToResumeAlignment) { boolean isResumed = isResumed(); - float toAlignmentForResumedState = isResumed && goingToUnstashedLauncherState() ? 1 : 0; + // If launcher is resumed, we show the icons when going to an unstashed launcher state + // or launcher state is not changed (e.g. in overview, launcher is paused and resumed). + float toAlignmentForResumedState = isResumed && (goingToUnstashedLauncherState() + || !goingToUnstashedLauncherStateChanged) ? 1 : 0; // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForResumedState.isAnimatingToValue(toAlignmentForResumedState)) { ObjectAnimator resumeAlignAnim = mIconAlignmentForResumedState @@ -379,7 +384,7 @@ import java.util.function.Supplier; } private void onIconAlignmentRatioChangedForStateTransition() { - if (!isResumed()) { + if (!isResumed() && mTaskBarRecentsAnimationListener == null) { return; } onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioForLauncherState); @@ -455,6 +460,7 @@ import java.util.function.Supplier; private void endGestureStateOverride(boolean finishedToApp) { mCallbacks.removeListener(this); + mTaskBarRecentsAnimationListener = null; // Update the resumed state immediately to ensure a seamless handoff boolean launcherResumed = !finishedToApp; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 3521ee33b7..be67136bf0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -33,6 +33,7 @@ import android.view.ViewConfiguration; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Utilities; +import com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.quickstep.AnimatedFloat; @@ -518,13 +519,40 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba */ public void setSystemGestureInProgress(boolean inProgress) { mIsSystemGestureInProgress = inProgress; - // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress. - if (!mIsSystemGestureInProgress) { + if (mIsSystemGestureInProgress) { + return; + } + + // Only update the following flags when system gesture is not in progress. + maybeResetStashedInAppAllApps(hasAnyFlag(FLAG_STASHED_IN_APP_IME) == mIsImeShowing); + if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != mIsImeShowing) { updateStateForFlag(FLAG_STASHED_IN_APP_IME, mIsImeShowing); applyState(TASKBAR_STASH_DURATION_FOR_IME, getTaskbarStashStartDelayForIme()); } } + /** + * Reset stashed in all apps only if no system gesture is in progress. + *

+ * Otherwise, the reset should be deferred until after the gesture is finished. + * + * @see #setSystemGestureInProgress + */ + public void maybeResetStashedInAppAllApps() { + maybeResetStashedInAppAllApps(true); + } + + private void maybeResetStashedInAppAllApps(boolean applyState) { + if (mIsSystemGestureInProgress) { + return; + } + + updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, false); + if (applyState) { + applyState(TaskbarAllAppsSlideInView.DEFAULT_CLOSE_DURATION); + } + } + /** * When hiding the IME, delay the unstash animation to align with the end of the transition. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java index 5d2d72af37..a37ebac2c3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java @@ -34,7 +34,7 @@ import java.util.Optional; public class TaskbarAllAppsSlideInView extends AbstractSlideInView implements Insettable, DeviceProfile.OnDeviceProfileChangeListener { static final int DEFAULT_OPEN_DURATION = 500; - static final int DEFAULT_CLOSE_DURATION = 200; + public static final int DEFAULT_CLOSE_DURATION = 200; private TaskbarAllAppsContainerView mAppsView; private OnCloseListener mOnCloseBeginListener; diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java index 32ebbe822e..f19b7de2f8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java @@ -16,7 +16,6 @@ package com.android.launcher3.taskbar.allapps; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_ALL_APPS; -import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_CLOSE_DURATION; import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_OPEN_DURATION; import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT; @@ -86,9 +85,9 @@ final class TaskbarAllAppsViewController { mSlideInView.setOnCloseBeginListener(() -> { AbstractFloatingView.closeOpenContainer( mContext, AbstractFloatingView.TYPE_ACTION_POPUP); - mTaskbarStashController.updateStateForFlag( - FLAG_STASHED_IN_APP_ALL_APPS, false); - mTaskbarStashController.applyState(DEFAULT_CLOSE_DURATION); + // Post in case view is closing due to gesture navigation. If a gesture is in progress, + // wait to unstash until after the gesture is finished. + mSlideInView.post(mTaskbarStashController::maybeResetStashedInAppAllApps); }); } } diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java index 332cbeb397..50be5ea565 100644 --- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java +++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java @@ -141,7 +141,10 @@ public class ClearAllButton extends Button { } applyPrimaryTranslation(); applySecondaryTranslation(); - mScrollAlpha = 1 - shift / orientationSize; + float clearAllSpacing = + recentsView.getPageSpacing() + recentsView.getClearAllExtraPageSpacing(); + clearAllSpacing = mIsRtl ? -clearAllSpacing : clearAllSpacing; + mScrollAlpha = Math.max((clearAllScroll + clearAllSpacing - scroll) / clearAllSpacing, 0); updateAlpha(); } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index e64e439779..3fa01690ac 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1289,10 +1289,11 @@ public abstract class RecentsView2dp 6dp 6dp + + + 24dp diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml index 27b13d7694..602dd6d05e 100644 --- a/res/values-sw600dp/dimens.xml +++ b/res/values-sw600dp/dimens.xml @@ -46,4 +46,7 @@ 16dp 16dp 56dp + + + 6dp diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 9a410704a5..e5e2217e26 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -381,8 +381,9 @@ - 22dp - 6dp + 28dp + 6dp + 6dp 48dp diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index d235180314..f7133c49dd 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -148,7 +148,8 @@ public class CellLayout extends ViewGroup { private boolean mVisualizeDropLocation = true; private RectF mVisualizeGridRect = new RectF(); private Paint mVisualizeGridPaint = new Paint(); - private int mGridVisualizationPadding; + private int mGridVisualizationPaddingX; + private int mGridVisualizationPaddingY; private int mGridVisualizationRoundingRadius; private float mGridAlpha = 0f; private int mGridColor = 0; @@ -260,8 +261,10 @@ public class CellLayout extends ViewGroup { mBackground.setAlpha(0); mGridColor = Themes.getAttrColor(getContext(), R.attr.workspaceAccentColor); - mGridVisualizationPadding = - res.getDimensionPixelSize(R.dimen.grid_visualization_cell_spacing); + mGridVisualizationPaddingX = res.getDimensionPixelSize( + R.dimen.grid_visualization_horizontal_cell_spacing); + mGridVisualizationPaddingY = res.getDimensionPixelSize( + R.dimen.grid_visualization_vertical_cell_spacing); mGridVisualizationRoundingRadius = res.getDimensionPixelSize(R.dimen.grid_visualization_rounding_radius); mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * deviceProfile.iconSizePx); @@ -591,8 +594,8 @@ public class CellLayout extends ViewGroup { protected void visualizeGrid(Canvas canvas) { DeviceProfile dp = mActivity.getDeviceProfile(); - int paddingX = (int) Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPadding); - int paddingY = (int) Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPadding); + int paddingX = Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPaddingX); + int paddingY = Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPaddingY); mVisualizeGridRect.set(paddingX, paddingY, mCellWidth - paddingX, mCellHeight - paddingY); diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java index b94cdbf226..54f769b421 100644 --- a/src/com/android/launcher3/DropTargetBar.java +++ b/src/com/android/launcher3/DropTargetBar.java @@ -252,8 +252,7 @@ public class DropTargetBar extends FrameLayout int overlap = start + leftButton.getMeasuredWidth() + rightButton.getMeasuredWidth() - end; if (overlap > 0) { - start -= overlap / 2; - end += overlap / 2; + end += overlap; } leftButton.layout(start, 0, start + leftButton.getMeasuredWidth(), diff --git a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java index 8a7cae90bc..f1276dd3c9 100644 --- a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java +++ b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java @@ -14,6 +14,8 @@ import android.os.SystemClock; import android.util.Log; import android.view.animation.Interpolator; +import androidx.annotation.AnyThread; + import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.anim.Interpolators; @@ -182,6 +184,7 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver { } } + @AnyThread private void updateOffset() { Message.obtain(mHandler, MSG_SET_NUM_PARALLAX, getNumPagesForWallpaperParallax(), 0, mWindowToken).sendToTarget(); @@ -206,9 +209,12 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - mWallpaperIsLiveWallpaper = - WallpaperManager.getInstance(mWorkspace.getContext()).getWallpaperInfo() != null; - updateOffset(); + UI_HELPER_EXECUTOR.execute(() -> { + // Updating the boolean on a background thread is fine as the assignments are atomic + mWallpaperIsLiveWallpaper = + WallpaperManager.getInstance(context).getWallpaperInfo() != null; + updateOffset(); + }); } private static final int MSG_START_ANIMATION = 1; diff --git a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java index 57f8bc7717..f42142ecf0 100644 --- a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java @@ -16,7 +16,6 @@ package com.android.launcher3.widget; -import android.annotation.SuppressLint; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.graphics.Canvas; @@ -31,9 +30,6 @@ import android.widget.RemoteViews; import com.android.launcher3.R; -import java.io.PrintWriter; -import java.io.StringWriter; - /** * A widget host views created while the host has not bind to the system service. */ @@ -73,34 +69,23 @@ public class DeferredAppWidgetHostView extends LauncherAppWidgetHostView { return; } - // Use double padding so that there is extra space between background and text + // Use double padding so that there is extra space between background and text if possible. int availableWidth = getMeasuredWidth() - 2 * (getPaddingLeft() + getPaddingRight()); + if (availableWidth <= 0) { + availableWidth = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight()); + } if (mSetupTextLayout != null && mSetupTextLayout.getText().equals(info.label) && mSetupTextLayout.getWidth() == availableWidth) { return; } - try { - mSetupTextLayout = new StaticLayout(info.label, mPaint, availableWidth, - Layout.Alignment.ALIGN_CENTER, 1, 0, true); - } catch (IllegalArgumentException e) { - @SuppressLint("DrawAllocation") StringWriter stringWriter = new StringWriter(); - @SuppressLint("DrawAllocation") PrintWriter printWriter = new PrintWriter(stringWriter); - mActivity.getDeviceProfile().dump(/*prefix=*/"", printWriter); - printWriter.flush(); - String message = "b/203530620 " - + "- availableWidth: " + availableWidth - + ", getMeasuredWidth: " + getMeasuredWidth() - + ", getPaddingLeft: " + getPaddingLeft() - + ", getPaddingRight: " + getPaddingRight() - + ", deviceProfile: " + stringWriter.toString(); - throw new IllegalArgumentException(message, e); - } + mSetupTextLayout = new StaticLayout(info.label, mPaint, availableWidth, + Layout.Alignment.ALIGN_CENTER, 1, 0, true); } @Override protected void onDraw(Canvas canvas) { if (mSetupTextLayout != null) { - canvas.translate(getPaddingLeft() * 2, + canvas.translate((getWidth() - mSetupTextLayout.getWidth()) / 2, (getHeight() - mSetupTextLayout.getHeight()) / 2); mSetupTextLayout.draw(canvas); }