diff options
Diffstat (limited to 'quickstep')
12 files changed, 148 insertions, 19 deletions
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index ca9c5771b1..f3e62c1d6e 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -158,6 +158,7 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.wm.shell.startingsurface.IStartingWindowListener; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -477,6 +478,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener }); } + /** Dump debug logs to bug report. */ + public void dump(@NonNull String prefix, @NonNull PrintWriter printWriter) {} + /** * Content is everything on screen except the background and the floating view (if any). * @@ -1046,7 +1050,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW && BlurUtils.supportsBlursOnWindows(); - MyDepthController depthController = new MyDepthController(mLauncher); + LaunchDepthController depthController = new LaunchDepthController(mLauncher); ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController.stateDepth, MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher)) .setDuration(APP_LAUNCH_DURATION); @@ -2047,11 +2051,14 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } - private static class MyDepthController extends DepthController { - MyDepthController(Launcher l) { - super(l); + private static class LaunchDepthController extends DepthController { + LaunchDepthController(QuickstepLauncher launcher) { + super(launcher); setCrossWindowBlursEnabled( CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled()); + // Make sure that the starting value matches the current depth set by the main + // controller. + stateDepth.setValue(launcher.getDepthController().stateDepth.getValue()); } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index ba6f1651ed..abf49eb195 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -50,6 +50,7 @@ import com.android.quickstep.util.GroupTask; import com.android.quickstep.views.RecentsView; import java.io.PrintWriter; +import java.util.Arrays; /** * A data source which integrates with a Launcher instance @@ -105,6 +106,10 @@ public class LauncherTaskbarUIController extends TaskbarUIController { // Restore the in-app display progress from before Taskbar was recreated. float[] prevProgresses = mControllers.getSharedState().inAppDisplayProgressMultiPropValues; + // Make a copy of the previous progress to set since updating the multiprop will update + // the property which also calls onInAppDisplayProgressChanged() which writes the current + // values into the shared state + prevProgresses = Arrays.copyOf(prevProgresses, prevProgresses.length); for (int i = 0; i < prevProgresses.length; i++) { mTaskbarInAppDisplayProgressMultiProp.get(i).setValue(prevProgresses[i]); } diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 9a9e0ba70c..9c463cb68c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -923,6 +923,15 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); } + /** + * Called whenever a new ui controller is set, and should update anything that depends on the + * ui controller. + */ + public void onUiControllerChanged() { + updateNavButtonInAppDisplayProgressForSysui(); + updateNavButtonTranslationY(); + } + @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "NavbarButtonsViewController:"); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 43feec716d..a1390aeabb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -591,9 +591,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { * Sets a new data-source for this taskbar instance */ public void setUIController(@NonNull TaskbarUIController uiController) { - mControllers.uiController.onDestroy(); - mControllers.uiController = uiController; - mControllers.uiController.init(mControllers); + mControllers.setUiController(uiController); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 66c2eb3314..d3f80e31cd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -196,6 +196,19 @@ public class TaskbarControllers { mPostInitCallbacks.clear(); } + /** + * Sets the ui controller. + */ + public void setUiController(@NonNull TaskbarUIController newUiController) { + uiController.onDestroy(); + uiController = newUiController; + uiController.init(this); + uiController.updateStateForSysuiFlags(mSharedState.sysuiStateFlags); + + // Notify that the ui controller has changed + navbarButtonsViewController.onUiControllerChanged(); + } + @Nullable public TaskbarSharedState getSharedState() { // This should only be null if called before init() and after destroy(). diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 2f13c5de44..b621a287c2 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -204,6 +204,8 @@ public class QuickstepLauncher extends Launcher { public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false; + protected static final String RING_APPEAR_ANIMATION_PREFIX = "RingAppearAnimation\t"; + private FixedContainerItems mAllAppsPredictions; private HotseatPredictionController mHotseatPredictionController; private DepthController mDepthController; @@ -472,6 +474,10 @@ public class QuickstepLauncher extends Launcher { public void onDestroy() { mAppTransitionManager.onActivityDestroyed(); if (mUnfoldTransitionProgressProvider != null) { + if (FeatureFlags.RECEIVE_UNFOLD_EVENTS_FROM_SYSUI.get()) { + SystemUiProxy.INSTANCE.get(this).setUnfoldAnimationListener(null); + } + mUnfoldTransitionProgressProvider.destroy(); } @@ -1332,5 +1338,8 @@ public class QuickstepLauncher extends Launcher { if (recentsView != null) { recentsView.getSplitSelectController().dump(prefix, writer); } + if (mAppTransitionManager != null) { + mAppTransitionManager.dump(prefix + "\t" + RING_APPEAR_ANIMATION_PREFIX, writer); + } } } diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java index 1913091695..eff53f3c85 100644 --- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java @@ -139,6 +139,7 @@ public class FallbackSwipeHandler extends mTmpMatrix.setScale(scale, scale, app.localBounds.exactCenterX(), app.localBounds.exactCenterY()); builder.setMatrix(mTmpMatrix).setAlpha(alpha); + builder.setShow(); } @Override diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java index 523a98ec4b..2256cbf14b 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; @@ -37,6 +38,7 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.RecentsAnimationControllerCompat; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Set; @@ -101,9 +103,22 @@ public class RecentsAnimationCallbacks implements RemoteAnimationTarget[] appTargets, RemoteAnimationTarget[] wallpaperTargets, Rect homeContentInsets, Rect minimizedHomeBounds) { + long appCount = Arrays.stream(appTargets) + .filter(app -> app.mode == MODE_CLOSING) + .count(); + if (appCount == 0) { + // Edge case, if there are no closing app targets, then Launcher has nothing to handle + ActiveGestureLog.INSTANCE.addLog( + /* event= */ "RecentsAnimationCallbacks.onAnimationStart (canceled)", + /* extras= */ 0, + /* gestureEvent= */ START_RECENTS_ANIMATION); + notifyAnimationCanceled(); + animationController.finish(false /* toHome */, false /* sendUserLeaveHint */); + return; + } + mController = new RecentsAnimationController(animationController, mAllowMinimizeSplitScreen, this::onAnimationFinished); - if (mCancelled) { Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), mController::finishAnimationToApp); diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 410ba21866..eacca0dbab 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -19,6 +19,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 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.NavigationMode.NO_BUTTON; import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS; import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED; import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED; @@ -37,6 +38,7 @@ import androidx.annotation.UiThread; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.util.DisplayController; import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.views.DesktopTaskView; @@ -162,10 +164,16 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn for (RemoteAnimationTarget compat : appearedTaskTargets) { if (compat.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME - && activityInterface.getCreatedActivity() instanceof RecentsActivity) { - // When receive opening home activity while recents is running, enter home - // and dismiss recents. - ((RecentsActivity) activityInterface.getCreatedActivity()).startHome(); + && activityInterface.getCreatedActivity() instanceof RecentsActivity + && DisplayController.getNavigationMode(mCtx) != NO_BUTTON) { + // The only time we get onTasksAppeared() in button navigation with a + // 3p launcher is if the user goes to overview first, and in this case we + // can immediately finish the transition + RecentsView recentsView = + activityInterface.getCreatedActivity().getOverviewPanel(); + if (recentsView != null) { + recentsView.finishRecentsAnimation(true, null); + } return; } } diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java index ab70272852..eac09ad7dc 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java @@ -103,7 +103,8 @@ public class ProgressDelegateInputConsumer implements InputConsumer, mStateCallback = new MultiStateCallback(STATE_NAMES); mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED, this::endRemoteAnimation); - mStateCallback.runOnceAtState(STATE_FLING_FINISHED, this::onFlingFinished); + mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED, + this::onFlingFinished); mSwipeDetector = new SingleAxisSwipeDetector(mContext, this, VERTICAL); mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false); diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java index 2eaff46715..6619dd86f6 100644 --- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java @@ -254,6 +254,9 @@ public class AllSetActivity extends Activity { mBinder.setSwipeUpProxy(isResumed() ? this::createSwipeUpProxy : null); mBinder.setOverviewTargetChangeListener(mBinder::preloadOverviewForSUWAllSet); mBinder.preloadOverviewForSUWAllSet(); + if (mTaskbarManager != null) { + mLauncherStartAnim = mTaskbarManager.createLauncherStartFromSuwAnim(MAX_SWIPE_DURATION); + } } @Override @@ -328,12 +331,9 @@ public class AllSetActivity extends Activity { mRootView.setAlpha(alpha); mRootView.setTranslationY((alpha - 1) * mSwipeUpShift); - if (mLauncherStartAnim == null && mTaskbarManager != null) { - mLauncherStartAnim = mTaskbarManager.createLauncherStartFromSuwAnim(MAX_SWIPE_DURATION); - } if (mLauncherStartAnim != null) { - mLauncherStartAnim.setPlayFraction(Utilities.mapBoundToRange( - mSwipeProgress.value, 0, 1, 0, 1, FAST_OUT_SLOW_IN)); + mLauncherStartAnim.setPlayFraction( + FAST_OUT_SLOW_IN.getInterpolation(mSwipeProgress.value)); } maybeResumeOrPauseBackgroundAnimation(); } diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java index 6d15e8be98..e0b527268c 100644 --- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java +++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java @@ -60,6 +60,8 @@ public class LauncherUnfoldAnimationController implements OnDeviceProfileChangeL private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider; private final UnfoldMoveFromCenterHotseatAnimator mUnfoldMoveFromCenterHotseatAnimator; private final UnfoldMoveFromCenterWorkspaceAnimator mUnfoldMoveFromCenterWorkspaceAnimator; + private final TransitionStatusProvider mExternalTransitionStatusProvider = + new TransitionStatusProvider(); private PreemptiveUnfoldTransitionProgressProvider mPreemptiveProgressProvider = null; private Boolean mIsTablet = null; @@ -88,6 +90,8 @@ public class LauncherUnfoldAnimationController implements OnDeviceProfileChangeL unfoldTransitionProgressProvider); } + unfoldTransitionProgressProvider.addCallback(mExternalTransitionStatusProvider); + mUnfoldMoveFromCenterHotseatAnimator = new UnfoldMoveFromCenterHotseatAnimator(launcher, windowManager, rotationChangeProvider); mUnfoldMoveFromCenterWorkspaceAnimator = new UnfoldMoveFromCenterWorkspaceAnimator(launcher, @@ -166,11 +170,26 @@ public class LauncherUnfoldAnimationController implements OnDeviceProfileChangeL } if (mIsTablet != null && dp.isTablet != mIsTablet) { - if (dp.isTablet && SystemUiProxy.INSTANCE.get(mLauncher).isActive()) { + // We should preemptively start the animation only if: + // - We changed to the unfolded screen + // - SystemUI IPC connection is alive, so we won't end up in a situation that we won't + // receive transition progress events from SystemUI later because there was no + // IPC connection established (e.g. because of SystemUI crash) + // - SystemUI has not already sent unfold animation progress events. This might happen + // if Launcher was not open during unfold, in this case we receive the configuration + // change only after we went back to home screen and we don't want to start the + // animation in this case. + if (dp.isTablet + && SystemUiProxy.INSTANCE.get(mLauncher).isActive() + && !mExternalTransitionStatusProvider.hasRun()) { // Preemptively start the unfold animation to make sure that we have drawn // the first frame of the animation before the screen gets unblocked preemptivelyStartAnimationOnNextFrame(); } + + if (!dp.isTablet) { + mExternalTransitionStatusProvider.onFolded(); + } } mIsTablet = dp.isTablet; @@ -222,4 +241,48 @@ public class LauncherUnfoldAnimationController implements OnDeviceProfileChangeL HOTSEAT_SCALE_PROPERTY.setValue(mLauncher.getHotseat(), value); } } + + /** + * Class to track the current status of the external transition provider (the events are coming + * from the SystemUI side through IPC), it allows to check if the transition has already + * finished or currently running on the SystemUI side since last unfold. + */ + private static class TransitionStatusProvider implements TransitionProgressListener { + + private boolean mHasRun = false; + + @Override + public void onTransitionStarted() { + markAsRun(); + } + + @Override + public void onTransitionProgress(float progress) { + markAsRun(); + } + + @Override + public void onTransitionFinished() { + markAsRun(); + } + + /** + * Called when the device is folded, so we can reset the status of the animation + */ + public void onFolded() { + mHasRun = false; + } + + /** + * Returns true if there was an animation already (or it is currently running) after + * unfolding the device + */ + public boolean hasRun() { + return mHasRun; + } + + private void markAsRun() { + mHasRun = true; + } + } } |