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