Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/Interpolators.java +6 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,12 @@ public class Interpolators { public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( 0.05f, 0.7f, 0.1f, 1f); /** * The standard accelerating interpolator that should be used on every regular movement of * content that is disappearing e.g. when moving off screen. */ public static final Interpolator STANDARD_ACCELERATE = new PathInterpolator(0.3f, 0f, 1f, 1f); /** * The standard decelerating interpolator that should be used on every regular movement of * content that is appearing e.g. when coming from off screen. Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/MinimizeAnimator.kt +37 −13 Original line number Diff line number Diff line Loading @@ -19,52 +19,76 @@ package com.android.wm.shell.shared.animation import android.animation.Animator import android.animation.AnimatorSet import android.animation.ValueAnimator import android.util.DisplayMetrics import android.content.Context import android.os.Handler import android.view.Choreographer import android.view.SurfaceControl.Transaction import android.view.animation.LinearInterpolator import android.view.animation.PathInterpolator import android.window.TransitionInfo.Change import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MINIMIZE_WINDOW import com.android.internal.jank.InteractionJankMonitor /** Creates minimization animation */ object MinimizeAnimator { private const val MINIMIZE_ANIM_ALPHA_DURATION_MS = 100L private val STANDARD_ACCELERATE = PathInterpolator(0.3f, 0f, 1f, 1f) private val minimizeBoundsAnimationDef = WindowAnimator.BoundsAnimationParams( durationMs = 200, endOffsetYDp = 12f, endScale = 0.97f, interpolator = STANDARD_ACCELERATE, interpolator = Interpolators.STANDARD_ACCELERATE, ) /** * Creates a minimize animator for given task [Change]. * * @param onAnimFinish finish-callback for the animation, note that this is called on the same * thread as the animation itself. * @param animationHandler the Handler that the animation is running on. */ @JvmStatic fun create( displayMetrics: DisplayMetrics, context: Context, change: Change, transaction: Transaction, onAnimFinish: (Animator) -> Unit, interactionJankMonitor: InteractionJankMonitor, animationHandler: Handler, ): Animator { val boundsAnimator = WindowAnimator.createBoundsAnimator( displayMetrics, context.resources.displayMetrics, minimizeBoundsAnimationDef, change, transaction, ) val alphaAnimator = ValueAnimator.ofFloat(1f, 0f).apply { duration = MINIMIZE_ANIM_ALPHA_DURATION_MS interpolator = LinearInterpolator() interpolator = Interpolators.LINEAR addUpdateListener { animation -> transaction.setAlpha(change.leash, animation.animatedValue as Float).apply() transaction .setAlpha(change.leash, animation.animatedValue as Float) .setFrameTimeline(Choreographer.getInstance().vsyncId) .apply() } } val listener = object : Animator.AnimatorListener { override fun onAnimationEnd(animator: Animator) = onAnimFinish(animator) override fun onAnimationCancel(animator: Animator) = Unit override fun onAnimationStart(animator: Animator) { interactionJankMonitor.begin( change.leash, context, animationHandler, CUJ_DESKTOP_MODE_MINIMIZE_WINDOW, ) } override fun onAnimationCancel(animator: Animator) { interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW) } override fun onAnimationRepeat(animator: Animator) = Unit override fun onAnimationStart(animator: Animator) = Unit override fun onAnimationEnd(animator: Animator) { interactionJankMonitor.end(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW) onAnimFinish(animator) } } return AnimatorSet().apply { playTogether(boundsAnimator, alphaAnimator) Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java +19 −10 Original line number Diff line number Diff line Loading @@ -162,22 +162,31 @@ public abstract class WMShellConcurrencyModule { } } /** * Provide a Shell animation-thread Executor. */ /** Provide a Shell animation-thread Handler. */ @WMSingleton @Provides @ShellAnimationThread public static ShellExecutor provideShellAnimationExecutor() { HandlerThread shellAnimationThread = new HandlerThread("wmshell.anim", THREAD_PRIORITY_DISPLAY); shellAnimationThread.start(); public static Handler provideShellAnimationHandler() { HandlerThread animThread = new HandlerThread("wmshell.anim", THREAD_PRIORITY_DISPLAY); animThread.start(); if (Build.IS_DEBUGGABLE) { shellAnimationThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER); shellAnimationThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS, animThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER); animThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS, MSGQ_SLOW_DELIVERY_THRESHOLD_MS); } return new HandlerExecutor(Handler.createAsync(shellAnimationThread.getLooper())); return Handler.createAsync(animThread.getLooper()); } /** * Provide a Shell animation-thread Executor. */ @WMSingleton @Provides @ShellAnimationThread public static ShellExecutor provideShellAnimationExecutor( @ShellAnimationThread Handler animHandler ) { return new HandlerExecutor(animHandler); } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +9 −6 Original line number Diff line number Diff line Loading @@ -431,9 +431,10 @@ public abstract class WMShellModule { Transitions transitions, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor) { @ShellAnimationThread ShellExecutor animExecutor, @ShellAnimationThread Handler animHandler) { return new FreeformTaskTransitionHandler( transitions, displayController, mainExecutor, animExecutor); transitions, displayController, mainExecutor, animExecutor, animHandler); } @WMSingleton Loading Loading @@ -1101,8 +1102,9 @@ public abstract class WMShellModule { Context context, @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor, @ShellMainThread Handler handler) { return new CloseDesktopTaskTransitionHandler(context, mainExecutor, animExecutor, handler); @ShellAnimationThread Handler animHandler) { return new CloseDesktopTaskTransitionHandler(context, mainExecutor, animExecutor, animHandler); } @WMSingleton Loading @@ -1110,9 +1112,10 @@ public abstract class WMShellModule { static DesktopMinimizationTransitionHandler provideDesktopMinimizationTransitionHandler( @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor, DisplayController displayController) { DisplayController displayController, @ShellAnimationThread Handler mainHandler) { return new DesktopMinimizationTransitionHandler(mainExecutor, animExecutor, displayController); displayController, mainHandler); } @WMSingleton Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/CloseDesktopTaskTransitionHandler.kt +2 −3 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import com.android.app.animation.Interpolators import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_CLOSE_TASK import com.android.internal.jank.InteractionJankMonitor import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.transition.Transitions import java.util.function.Supplier Loading @@ -49,7 +48,7 @@ constructor( private val mainExecutor: ShellExecutor, private val animExecutor: ShellExecutor, private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }, @ShellMainThread private val handler: Handler, private val animHandler: Handler, ) : Transitions.TransitionHandler { private val runningAnimations = mutableMapOf<IBinder, List<Animator>>() Loading Loading @@ -95,7 +94,7 @@ constructor( interactionJankMonitor.begin( lastChangeLeash, context, handler, animHandler, CUJ_DESKTOP_MODE_CLOSE_TASK, ) } Loading Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/Interpolators.java +6 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,12 @@ public class Interpolators { public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( 0.05f, 0.7f, 0.1f, 1f); /** * The standard accelerating interpolator that should be used on every regular movement of * content that is disappearing e.g. when moving off screen. */ public static final Interpolator STANDARD_ACCELERATE = new PathInterpolator(0.3f, 0f, 1f, 1f); /** * The standard decelerating interpolator that should be used on every regular movement of * content that is appearing e.g. when coming from off screen. Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/MinimizeAnimator.kt +37 −13 Original line number Diff line number Diff line Loading @@ -19,52 +19,76 @@ package com.android.wm.shell.shared.animation import android.animation.Animator import android.animation.AnimatorSet import android.animation.ValueAnimator import android.util.DisplayMetrics import android.content.Context import android.os.Handler import android.view.Choreographer import android.view.SurfaceControl.Transaction import android.view.animation.LinearInterpolator import android.view.animation.PathInterpolator import android.window.TransitionInfo.Change import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MINIMIZE_WINDOW import com.android.internal.jank.InteractionJankMonitor /** Creates minimization animation */ object MinimizeAnimator { private const val MINIMIZE_ANIM_ALPHA_DURATION_MS = 100L private val STANDARD_ACCELERATE = PathInterpolator(0.3f, 0f, 1f, 1f) private val minimizeBoundsAnimationDef = WindowAnimator.BoundsAnimationParams( durationMs = 200, endOffsetYDp = 12f, endScale = 0.97f, interpolator = STANDARD_ACCELERATE, interpolator = Interpolators.STANDARD_ACCELERATE, ) /** * Creates a minimize animator for given task [Change]. * * @param onAnimFinish finish-callback for the animation, note that this is called on the same * thread as the animation itself. * @param animationHandler the Handler that the animation is running on. */ @JvmStatic fun create( displayMetrics: DisplayMetrics, context: Context, change: Change, transaction: Transaction, onAnimFinish: (Animator) -> Unit, interactionJankMonitor: InteractionJankMonitor, animationHandler: Handler, ): Animator { val boundsAnimator = WindowAnimator.createBoundsAnimator( displayMetrics, context.resources.displayMetrics, minimizeBoundsAnimationDef, change, transaction, ) val alphaAnimator = ValueAnimator.ofFloat(1f, 0f).apply { duration = MINIMIZE_ANIM_ALPHA_DURATION_MS interpolator = LinearInterpolator() interpolator = Interpolators.LINEAR addUpdateListener { animation -> transaction.setAlpha(change.leash, animation.animatedValue as Float).apply() transaction .setAlpha(change.leash, animation.animatedValue as Float) .setFrameTimeline(Choreographer.getInstance().vsyncId) .apply() } } val listener = object : Animator.AnimatorListener { override fun onAnimationEnd(animator: Animator) = onAnimFinish(animator) override fun onAnimationCancel(animator: Animator) = Unit override fun onAnimationStart(animator: Animator) { interactionJankMonitor.begin( change.leash, context, animationHandler, CUJ_DESKTOP_MODE_MINIMIZE_WINDOW, ) } override fun onAnimationCancel(animator: Animator) { interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW) } override fun onAnimationRepeat(animator: Animator) = Unit override fun onAnimationStart(animator: Animator) = Unit override fun onAnimationEnd(animator: Animator) { interactionJankMonitor.end(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW) onAnimFinish(animator) } } return AnimatorSet().apply { playTogether(boundsAnimator, alphaAnimator) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java +19 −10 Original line number Diff line number Diff line Loading @@ -162,22 +162,31 @@ public abstract class WMShellConcurrencyModule { } } /** * Provide a Shell animation-thread Executor. */ /** Provide a Shell animation-thread Handler. */ @WMSingleton @Provides @ShellAnimationThread public static ShellExecutor provideShellAnimationExecutor() { HandlerThread shellAnimationThread = new HandlerThread("wmshell.anim", THREAD_PRIORITY_DISPLAY); shellAnimationThread.start(); public static Handler provideShellAnimationHandler() { HandlerThread animThread = new HandlerThread("wmshell.anim", THREAD_PRIORITY_DISPLAY); animThread.start(); if (Build.IS_DEBUGGABLE) { shellAnimationThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER); shellAnimationThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS, animThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER); animThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS, MSGQ_SLOW_DELIVERY_THRESHOLD_MS); } return new HandlerExecutor(Handler.createAsync(shellAnimationThread.getLooper())); return Handler.createAsync(animThread.getLooper()); } /** * Provide a Shell animation-thread Executor. */ @WMSingleton @Provides @ShellAnimationThread public static ShellExecutor provideShellAnimationExecutor( @ShellAnimationThread Handler animHandler ) { return new HandlerExecutor(animHandler); } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +9 −6 Original line number Diff line number Diff line Loading @@ -431,9 +431,10 @@ public abstract class WMShellModule { Transitions transitions, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor) { @ShellAnimationThread ShellExecutor animExecutor, @ShellAnimationThread Handler animHandler) { return new FreeformTaskTransitionHandler( transitions, displayController, mainExecutor, animExecutor); transitions, displayController, mainExecutor, animExecutor, animHandler); } @WMSingleton Loading Loading @@ -1101,8 +1102,9 @@ public abstract class WMShellModule { Context context, @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor, @ShellMainThread Handler handler) { return new CloseDesktopTaskTransitionHandler(context, mainExecutor, animExecutor, handler); @ShellAnimationThread Handler animHandler) { return new CloseDesktopTaskTransitionHandler(context, mainExecutor, animExecutor, animHandler); } @WMSingleton Loading @@ -1110,9 +1112,10 @@ public abstract class WMShellModule { static DesktopMinimizationTransitionHandler provideDesktopMinimizationTransitionHandler( @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor, DisplayController displayController) { DisplayController displayController, @ShellAnimationThread Handler mainHandler) { return new DesktopMinimizationTransitionHandler(mainExecutor, animExecutor, displayController); displayController, mainHandler); } @WMSingleton Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/CloseDesktopTaskTransitionHandler.kt +2 −3 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import com.android.app.animation.Interpolators import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_CLOSE_TASK import com.android.internal.jank.InteractionJankMonitor import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.transition.Transitions import java.util.function.Supplier Loading @@ -49,7 +48,7 @@ constructor( private val mainExecutor: ShellExecutor, private val animExecutor: ShellExecutor, private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }, @ShellMainThread private val handler: Handler, private val animHandler: Handler, ) : Transitions.TransitionHandler { private val runningAnimations = mutableMapOf<IBinder, List<Animator>>() Loading Loading @@ -95,7 +94,7 @@ constructor( interactionJankMonitor.begin( lastChangeLeash, context, handler, animHandler, CUJ_DESKTOP_MODE_CLOSE_TASK, ) } Loading