Loading packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt→packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt +85 −76 Original line number Original line Diff line number Diff line Loading @@ -45,13 +45,13 @@ import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils import com.android.internal.policy.ScreenDecorationsUtils import kotlin.math.roundToInt import kotlin.math.roundToInt private const val TAG = "ActivityLaunchAnimator" private const val TAG = "ActivityTransitionAnimator" /** /** * A class that allows activities to be started in a seamless way from a view that is transforming * A class that allows activities to be started in a seamless way from a view that is transforming * nicely into the starting window. * nicely into the starting window. */ */ class ActivityLaunchAnimator( class ActivityTransitionAnimator( /** The animator used when animating a View into an app. */ /** The animator used when animating a View into an app. */ private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, Loading Loading @@ -97,7 +97,7 @@ class ActivityLaunchAnimator( ) ) // TODO(b/288507023): Remove this flag. // TODO(b/288507023): Remove this flag. @JvmField val DEBUG_LAUNCH_ANIMATION = Build.IS_DEBUGGABLE @JvmField val DEBUG_TRANSITION_ANIMATION = Build.IS_DEBUGGABLE private val DEFAULT_TRANSITION_ANIMATOR = TransitionAnimator(TIMINGS, INTERPOLATORS) private val DEFAULT_TRANSITION_ANIMATOR = TransitionAnimator(TIMINGS, INTERPOLATORS) private val DEFAULT_DIALOG_TO_APP_ANIMATOR = private val DEFAULT_DIALOG_TO_APP_ANIMATOR = Loading @@ -113,13 +113,13 @@ class ActivityLaunchAnimator( private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f) private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f) /** The time we wait before timing out the remote animation after starting the intent. */ /** The time we wait before timing out the remote animation after starting the intent. */ private const val LAUNCH_TIMEOUT = 1_000L private const val TRANSITION_TIMEOUT = 1_000L /** /** * The time we wait before we Log.wtf because the remote animation was neither started or * The time we wait before we Log.wtf because the remote animation was neither started or * cancelled by WM. * cancelled by WM. */ */ private const val LONG_LAUNCH_TIMEOUT = 5_000L private const val LONG_TRANSITION_TIMEOUT = 5_000L } } /** /** Loading @@ -134,20 +134,20 @@ class ActivityLaunchAnimator( /** Top-level listener that can be used to notify all registered [listeners]. */ /** Top-level listener that can be used to notify all registered [listeners]. */ private val lifecycleListener = private val lifecycleListener = object : Listener { object : Listener { override fun onLaunchAnimationStart() { override fun onTransitionAnimationStart() { listeners.forEach { it.onLaunchAnimationStart() } listeners.forEach { it.onTransitionAnimationStart() } } } override fun onLaunchAnimationEnd() { override fun onTransitionAnimationEnd() { listeners.forEach { it.onLaunchAnimationEnd() } listeners.forEach { it.onTransitionAnimationEnd() } } } override fun onLaunchAnimationProgress(linearProgress: Float) { override fun onTransitionAnimationProgress(linearProgress: Float) { listeners.forEach { it.onLaunchAnimationProgress(linearProgress) } listeners.forEach { it.onTransitionAnimationProgress(linearProgress) } } } override fun onLaunchAnimationCancelled() { override fun onTransitionAnimationCancelled() { listeners.forEach { it.onLaunchAnimationCancelled() } listeners.forEach { it.onTransitionAnimationCancelled() } } } } } Loading Loading @@ -188,7 +188,7 @@ class ActivityLaunchAnimator( val callback = val callback = this.callback this.callback ?: throw IllegalStateException( ?: throw IllegalStateException( "ActivityLaunchAnimator.callback must be set before using this animator" "ActivityTransitionAnimator.callback must be set before using this animator" ) ) val runner = createRunner(controller) val runner = createRunner(controller) val runnerDelegate = runner.delegate!! val runnerDelegate = runner.delegate!! Loading Loading @@ -260,7 +260,7 @@ class ActivityLaunchAnimator( callOnIntentStartedOnMainThread(willAnimate) callOnIntentStartedOnMainThread(willAnimate) } } } else { } else { if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onIntentStarted(willAnimate=$willAnimate) " + "Calling controller.onIntentStarted(willAnimate=$willAnimate) " + Loading Loading @@ -293,7 +293,7 @@ class ActivityLaunchAnimator( } } } } /** Add a [Listener] that can listen to launch animations. */ /** Add a [Listener] that can listen to transition animations. */ fun addListener(listener: Listener) { fun addListener(listener: Listener) { listeners.add(listener) listeners.add(listener) } } Loading Loading @@ -340,24 +340,24 @@ class ActivityLaunchAnimator( } } interface Listener { interface Listener { /** Called when an activity launch animation started. */ /** Called when an activity transition animation started. */ fun onLaunchAnimationStart() {} fun onTransitionAnimationStart() {} /** /** * Called when an activity launch animation is finished. This will be called if and only if * Called when an activity transition animation is finished. This will be called if and only * [onLaunchAnimationStart] was called earlier. * if [onTransitionAnimationStart] was called earlier. */ */ fun onLaunchAnimationEnd() {} fun onTransitionAnimationEnd() {} /** /** * The animation was cancelled. Note that [onLaunchAnimationEnd] will still be called after * The animation was cancelled. Note that [onTransitionAnimationEnd] will still be called * this if the animation was already started, i.e. if [onLaunchAnimationStart] was called * after this if the animation was already started, i.e. if [onTransitionAnimationStart] was * before the cancellation. * called before the cancellation. */ */ fun onLaunchAnimationCancelled() {} fun onTransitionAnimationCancelled() {} /** Called when an activity launch animation made progress. */ /** Called when an activity transition animation made progress. */ fun onLaunchAnimationProgress(linearProgress: Float) {} fun onTransitionAnimationProgress(linearProgress: Float) {} } } /** /** Loading @@ -383,9 +383,10 @@ class ActivityLaunchAnimator( // issues. // issues. if (view !is LaunchableView) { if (view !is LaunchableView) { throw IllegalArgumentException( throw IllegalArgumentException( "An ActivityLaunchAnimator.Controller was created from a View that does " + "An ActivityTransitionAnimator.Controller was created from a View that " + "not implement LaunchableView. This can lead to subtle bugs where the" + "does not implement LaunchableView. This can lead to subtle bugs " + " visibility of the View we are launching from is not what we expected." "where the visibility of the View we are launching from is not what " + "we expected." ) ) } } Loading @@ -411,11 +412,11 @@ class ActivityLaunchAnimator( get() = false get() = false /** /** * Whether the expandable controller by this [Controller] is below the launching window that * Whether the expandable controller by this [Controller] is below the window that is going * is going to be animated. * to be animated. * * * This should be `false` when launching an app from the shade or status bar, given that * This should be `false` when animating an app from or to the shade or status bar, given * they are drawn above all apps. This is usually `true` when using this launcher in a * that they are drawn above all apps. This is usually `true` when using this animator in a * normal app or a launcher, that are drawn below the animating activity/window. * normal app or a launcher, that are drawn below the animating activity/window. */ */ val isBelowAnimatingWindow: Boolean val isBelowAnimatingWindow: Boolean Loading @@ -432,10 +433,11 @@ class ActivityLaunchAnimator( * after this if the animation was already started, i.e. if [onTransitionAnimationStart] was * after this if the animation was already started, i.e. if [onTransitionAnimationStart] was * called before the cancellation. * called before the cancellation. * * * If this launch animation affected the occlusion state of the keyguard, WM will provide us * If this transition animation affected the occlusion state of the keyguard, WM will * with [newKeyguardOccludedState] so that we can set the occluded state appropriately. * provide us with [newKeyguardOccludedState] so that we can set the occluded state * appropriately. */ */ fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {} fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {} } } /** /** Loading @@ -449,24 +451,24 @@ class ActivityLaunchAnimator( ) : Listener { ) : Listener { var cancelled = false var cancelled = false override fun onLaunchAnimationStart() { override fun onTransitionAnimationStart() { delegate?.onLaunchAnimationStart() delegate?.onTransitionAnimationStart() } } override fun onLaunchAnimationProgress(linearProgress: Float) { override fun onTransitionAnimationProgress(linearProgress: Float) { delegate?.onLaunchAnimationProgress(linearProgress) delegate?.onTransitionAnimationProgress(linearProgress) } } override fun onLaunchAnimationEnd() { override fun onTransitionAnimationEnd() { delegate?.onLaunchAnimationEnd() delegate?.onTransitionAnimationEnd() if (!cancelled) { if (!cancelled) { onAnimationComplete.invoke() onAnimationComplete.invoke() } } } } override fun onLaunchAnimationCancelled() { override fun onTransitionAnimationCancelled() { cancelled = true cancelled = true delegate?.onLaunchAnimationCancelled() delegate?.onTransitionAnimationCancelled() onAnimationComplete.invoke() onAnimationComplete.invoke() } } } } Loading @@ -475,7 +477,7 @@ class ActivityLaunchAnimator( inner class Runner( inner class Runner( controller: Controller, controller: Controller, callback: Callback, callback: Callback, /** The animator to use to animate the window launch. */ /** The animator to use to animate the window transition. */ transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, /** Listener for animation lifecycle events. */ /** Listener for animation lifecycle events. */ listener: Listener? = null listener: Listener? = null Loading Loading @@ -543,7 +545,7 @@ class ActivityLaunchAnimator( private val callback: Callback, private val callback: Callback, /** Listener for animation lifecycle events. */ /** Listener for animation lifecycle events. */ private val listener: Listener? = null, private val listener: Listener? = null, /** The animator to use to animate the window launch. */ /** The animator to use to animate the window transition. */ private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, /** /** Loading Loading @@ -574,8 +576,8 @@ class ActivityLaunchAnimator( private var animation: TransitionAnimator.Animation? = null private var animation: TransitionAnimator.Animation? = null /** /** * A timeout to cancel the launch animation if the remote animation is not started or * A timeout to cancel the transition animation if the remote animation is not started or * cancelled within [LAUNCH_TIMEOUT] milliseconds after the intent was started. * cancelled within [TRANSITION_TIMEOUT] milliseconds after the intent was started. * * * Note that this is important to keep this a Runnable (and not a Kotlin lambda), otherwise * Note that this is important to keep this a Runnable (and not a Kotlin lambda), otherwise * it will be automatically converted when posted and we wouldn't be able to remove it after * it will be automatically converted when posted and we wouldn't be able to remove it after Loading @@ -585,21 +587,22 @@ class ActivityLaunchAnimator( /** /** * A long timeout to Log.wtf (signaling a bug in WM) when the remote animation wasn't * A long timeout to Log.wtf (signaling a bug in WM) when the remote animation wasn't * started or cancelled within [LONG_LAUNCH_TIMEOUT] milliseconds after the intent was * started or cancelled within [LONG_TRANSITION_TIMEOUT] milliseconds after the intent was * started. * started. */ */ private var onLongTimeout = Runnable { private var onLongTimeout = Runnable { Log.wtf( Log.wtf( TAG, TAG, "The remote animation was neither cancelled or started within $LONG_LAUNCH_TIMEOUT" "The remote animation was neither cancelled or started within " + "$LONG_TRANSITION_TIMEOUT" ) ) } } @UiThread @UiThread internal fun postTimeouts() { internal fun postTimeouts() { if (timeoutHandler != null) { if (timeoutHandler != null) { timeoutHandler.postDelayed(onTimeout, LAUNCH_TIMEOUT) timeoutHandler.postDelayed(onTimeout, TRANSITION_TIMEOUT) timeoutHandler.postDelayed(onLongTimeout, LONG_LAUNCH_TIMEOUT) timeoutHandler.postDelayed(onLongTimeout, LONG_TRANSITION_TIMEOUT) } } } } Loading Loading @@ -670,14 +673,14 @@ class ActivityLaunchAnimator( Log.i(TAG, "Aborting the animation as no window is opening") Log.i(TAG, "Aborting the animation as no window is opening") iCallback?.invoke() iCallback?.invoke() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationCancelled() [no window opening]" "Calling controller.onTransitionAnimationCancelled() [no window opening]" ) ) } } controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() listener?.onLaunchAnimationCancelled() listener?.onTransitionAnimationCancelled() return return } } Loading Loading @@ -720,27 +723,29 @@ class ActivityLaunchAnimator( val controller = val controller = object : Controller by delegate { object : Controller by delegate { override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { listener?.onLaunchAnimationStart() listener?.onTransitionAnimationStart() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationStart(isExpandingFullyAbove=" + "Calling controller.onTransitionAnimationStart(" + "$isExpandingFullyAbove) [controller=$delegate]" "isExpandingFullyAbove=$isExpandingFullyAbove) " + "[controller=$delegate]" ) ) } } delegate.onTransitionAnimationStart(isExpandingFullyAbove) delegate.onTransitionAnimationStart(isExpandingFullyAbove) } } override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { listener?.onLaunchAnimationEnd() listener?.onTransitionAnimationEnd() iCallback?.invoke() iCallback?.invoke() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationEnd(isExpandingFullyAbove=" + "Calling controller.onTransitionAnimationEnd(" + "$isExpandingFullyAbove) [controller=$delegate]" "isExpandingFullyAbove=$isExpandingFullyAbove) " + "[controller=$delegate]" ) ) } } delegate.onTransitionAnimationEnd(isExpandingFullyAbove) delegate.onTransitionAnimationEnd(isExpandingFullyAbove) Loading @@ -758,7 +763,7 @@ class ActivityLaunchAnimator( } } navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) } navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) } listener?.onLaunchAnimationProgress(linearProgress) listener?.onTransitionAnimationProgress(linearProgress) delegate.onTransitionAnimationProgress(state, progress, linearProgress) delegate.onTransitionAnimationProgress(state, progress, linearProgress) } } } } Loading Loading @@ -904,7 +909,7 @@ class ActivityLaunchAnimator( } } private fun onAnimationTimedOut() { private fun onAnimationTimedOut() { // The remote animation was cancelled by WM, so we already cancelled the launch // The remote animation was cancelled by WM, so we already cancelled the transition // animation. // animation. if (cancelled) { if (cancelled) { return return Loading @@ -913,18 +918,21 @@ class ActivityLaunchAnimator( Log.w(TAG, "Remote animation timed out") Log.w(TAG, "Remote animation timed out") timedOut = true timedOut = true if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d(TAG, "Calling controller.onLaunchAnimationCancelled() [animation timed out]") Log.d( TAG, "Calling controller.onTransitionAnimationCancelled() [animation timed out]" ) } } controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() listener?.onLaunchAnimationCancelled() listener?.onTransitionAnimationCancelled() } } @UiThread @UiThread override fun onAnimationCancelled() { override fun onAnimationCancelled() { removeTimeouts() removeTimeouts() // The short timeout happened, so we already cancelled the launch animation. // The short timeout happened, so we already cancelled the transition animation. if (timedOut) { if (timedOut) { return return } } Loading @@ -934,14 +942,15 @@ class ActivityLaunchAnimator( animation?.cancel() animation?.cancel() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationCancelled() [remote animation cancelled]", "Calling controller.onTransitionAnimationCancelled() [remote animation " + "cancelled]", ) ) } } controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() listener?.onLaunchAnimationCancelled() listener?.onTransitionAnimationCancelled() } } private fun IRemoteAnimationFinishedCallback.invoke() { private fun IRemoteAnimationFinishedCallback.invoke() { Loading packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt +3 −3 Original line number Original line Diff line number Diff line Loading @@ -17,10 +17,10 @@ package com.android.systemui.animation package com.android.systemui.animation /** /** * A base class to easily create an implementation of [ActivityLaunchAnimator.Controller] which * A base class to easily create an implementation of [ActivityTransitionAnimator.Controller] which * delegates most of its call to [delegate]. This is mostly useful for Java code which can't easily * delegates most of its call to [delegate]. This is mostly useful for Java code which can't easily * create such a delegated class. * create such a delegated class. */ */ open class DelegateLaunchAnimatorController( open class DelegateLaunchAnimatorController( protected val delegate: ActivityLaunchAnimator.Controller protected val delegate: ActivityTransitionAnimator.Controller ) : ActivityLaunchAnimator.Controller by delegate ) : ActivityTransitionAnimator.Controller by delegate packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt +15 −14 Original line number Original line Diff line number Diff line Loading @@ -62,13 +62,14 @@ constructor( private val isForTesting: Boolean = false, private val isForTesting: Boolean = false, ) { ) { private companion object { private companion object { private val TIMINGS = ActivityLaunchAnimator.TIMINGS private val TIMINGS = ActivityTransitionAnimator.TIMINGS // We use the same interpolator for X and Y axis to make sure the dialog does not move out // We use the same interpolator for X and Y axis to make sure the dialog does not move out // of the screen bounds during the animation. // of the screen bounds during the animation. private val INTERPOLATORS = private val INTERPOLATORS = ActivityLaunchAnimator.INTERPOLATORS.copy( ActivityTransitionAnimator.INTERPOLATORS.copy( positionXInterpolator = ActivityLaunchAnimator.INTERPOLATORS.positionInterpolator positionXInterpolator = ActivityTransitionAnimator.INTERPOLATORS.positionInterpolator ) ) } } Loading Loading @@ -319,9 +320,9 @@ constructor( } } /** /** * Create an [ActivityLaunchAnimator.Controller] that can be used to launch an activity from the * Create an [ActivityTransitionAnimator.Controller] that can be used to launch an activity from * dialog that contains [View]. Note that the dialog must have been shown using this animator, * the dialog that contains [View]. Note that the dialog must have been shown using this * otherwise this method will return null. * animator, otherwise this method will return null. * * * The returned controller will take care of dismissing the dialog at the right time after the * The returned controller will take care of dismissing the dialog at the right time after the * activity started, when the dialog to app animation is done (or when it is cancelled). If this * activity started, when the dialog to app animation is done (or when it is cancelled). If this Loading @@ -333,7 +334,7 @@ constructor( fun createActivityLaunchController( fun createActivityLaunchController( view: View, view: View, cujType: Int? = null, cujType: Int? = null, ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { val animatedDialog = val animatedDialog = openedDialogs.firstOrNull { openedDialogs.firstOrNull { it.dialog.window?.decorView?.viewRootImpl == view.viewRootImpl it.dialog.window?.decorView?.viewRootImpl == view.viewRootImpl Loading @@ -343,7 +344,7 @@ constructor( } } /** /** * Create an [ActivityLaunchAnimator.Controller] that can be used to launch an activity from * Create an [ActivityTransitionAnimator.Controller] that can be used to launch an activity from * [dialog]. Note that the dialog must have been shown using this animator, otherwise this * [dialog]. Note that the dialog must have been shown using this animator, otherwise this * method will return null. * method will return null. * * Loading @@ -357,7 +358,7 @@ constructor( fun createActivityLaunchController( fun createActivityLaunchController( dialog: Dialog, dialog: Dialog, cujType: Int? = null, cujType: Int? = null, ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { val animatedDialog = openedDialogs.firstOrNull { it.dialog == dialog } ?: return null val animatedDialog = openedDialogs.firstOrNull { it.dialog == dialog } ?: return null return createActivityLaunchController(animatedDialog, cujType) return createActivityLaunchController(animatedDialog, cujType) } } Loading @@ -365,7 +366,7 @@ constructor( private fun createActivityLaunchController( private fun createActivityLaunchController( animatedDialog: AnimatedDialog, animatedDialog: AnimatedDialog, cujType: Int? = null cujType: Int? = null ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { // At this point, we know that the intent of the caller is to dismiss the dialog to show // At this point, we know that the intent of the caller is to dismiss the dialog to show // an app, so we disable the exit animation into the source because we will never want to // an app, so we disable the exit animation into the source because we will never want to // run it anyways. // run it anyways. Loading @@ -384,12 +385,12 @@ constructor( val dialogContentWithBackground = animatedDialog.dialogContentWithBackground ?: return null val dialogContentWithBackground = animatedDialog.dialogContentWithBackground ?: return null val controller = val controller = ActivityLaunchAnimator.Controller.fromView(dialogContentWithBackground, cujType) ActivityTransitionAnimator.Controller.fromView(dialogContentWithBackground, cujType) ?: return null ?: return null // Wrap the controller into one that will instantly dismiss the dialog when the animation is // Wrap the controller into one that will instantly dismiss the dialog when the animation is // done or dismiss it normally (fading it out) if the animation is cancelled. // done or dismiss it normally (fading it out) if the animation is cancelled. return object : ActivityLaunchAnimator.Controller by controller { return object : ActivityTransitionAnimator.Controller by controller { override val isDialogLaunch = true override val isDialogLaunch = true override fun onIntentStarted(willAnimate: Boolean) { override fun onIntentStarted(willAnimate: Boolean) { Loading @@ -400,8 +401,8 @@ constructor( } } } } override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) { override fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean?) { controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() enableDialogDismiss() enableDialogDismiss() dialog.dismiss() dialog.dismiss() } } Loading packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt +6 −6 Original line number Original line Diff line number Diff line Loading @@ -21,14 +21,14 @@ import android.view.View /** A piece of UI that can be expanded into a Dialog or an Activity. */ /** A piece of UI that can be expanded into a Dialog or an Activity. */ interface Expandable { interface Expandable { /** /** * Create an [ActivityLaunchAnimator.Controller] that can be used to expand this [Expandable] * Create an [ActivityTransitionAnimator.Controller] that can be used to expand this * into an Activity, or return `null` if this [Expandable] should not be animated (e.g. if it is * [Expandable] into an Activity, or return `null` if this [Expandable] should not be animated * currently not attached or visible). * (e.g. if it is currently not attached or visible). * * * @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor] * @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor] * associated to the launch that will use this controller. * associated to the launch that will use this controller. */ */ fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller? fun activityLaunchController(cujType: Int? = null): ActivityTransitionAnimator.Controller? /** /** * Create a [DialogLaunchAnimator.Controller] that can be used to expand this [Expandable] into * Create a [DialogLaunchAnimator.Controller] that can be used to expand this [Expandable] into Loading @@ -49,8 +49,8 @@ interface Expandable { return object : Expandable { return object : Expandable { override fun activityLaunchController( override fun activityLaunchController( cujType: Int?, cujType: Int?, ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { return ActivityLaunchAnimator.Controller.fromView(view, cujType) return ActivityTransitionAnimator.Controller.fromView(view, cujType) } } override fun dialogLaunchController( override fun dialogLaunchController( Loading packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt +5 −5 Original line number Original line Diff line number Diff line Loading @@ -42,15 +42,15 @@ import kotlin.math.roundToInt private const val TAG = "GhostedViewLaunchAnimatorController" private const val TAG = "GhostedViewLaunchAnimatorController" /** /** * A base implementation of [ActivityLaunchAnimator.Controller] which creates a [ghost][GhostView] * A base implementation of [ActivityTransitionAnimator.Controller] which creates a * of [ghostedView] as well as an expandable background view, which are drawn and animated instead * [ghost][GhostView] of [ghostedView] as well as an expandable background view, which are drawn and * of the ghosted view. * animated instead of the ghosted view. * * * Important: [ghostedView] must be attached to a [ViewGroup] when calling this function and during * Important: [ghostedView] must be attached to a [ViewGroup] when calling this function and during * the animation. It must also implement [LaunchableView], otherwise an exception will be thrown * the animation. It must also implement [LaunchableView], otherwise an exception will be thrown * during this controller instantiation. * during this controller instantiation. * * * Note: Avoid instantiating this directly and call [ActivityLaunchAnimator.Controller.fromView] * Note: Avoid instantiating this directly and call [ActivityTransitionAnimator.Controller.fromView] * whenever possible instead. * whenever possible instead. */ */ open class GhostedViewLaunchAnimatorController open class GhostedViewLaunchAnimatorController Loading @@ -63,7 +63,7 @@ constructor( private val cujType: Int? = null, private val cujType: Int? = null, private var interactionJankMonitor: InteractionJankMonitor = private var interactionJankMonitor: InteractionJankMonitor = InteractionJankMonitor.getInstance(), InteractionJankMonitor.getInstance(), ) : ActivityLaunchAnimator.Controller { ) : ActivityTransitionAnimator.Controller { /** The container to which we will add the ghost view and expanding background. */ /** The container to which we will add the ghost view and expanding background. */ override var transitionContainer = ghostedView.rootView as ViewGroup override var transitionContainer = ghostedView.rootView as ViewGroup Loading Loading
packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt→packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt +85 −76 Original line number Original line Diff line number Diff line Loading @@ -45,13 +45,13 @@ import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils import com.android.internal.policy.ScreenDecorationsUtils import kotlin.math.roundToInt import kotlin.math.roundToInt private const val TAG = "ActivityLaunchAnimator" private const val TAG = "ActivityTransitionAnimator" /** /** * A class that allows activities to be started in a seamless way from a view that is transforming * A class that allows activities to be started in a seamless way from a view that is transforming * nicely into the starting window. * nicely into the starting window. */ */ class ActivityLaunchAnimator( class ActivityTransitionAnimator( /** The animator used when animating a View into an app. */ /** The animator used when animating a View into an app. */ private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, Loading Loading @@ -97,7 +97,7 @@ class ActivityLaunchAnimator( ) ) // TODO(b/288507023): Remove this flag. // TODO(b/288507023): Remove this flag. @JvmField val DEBUG_LAUNCH_ANIMATION = Build.IS_DEBUGGABLE @JvmField val DEBUG_TRANSITION_ANIMATION = Build.IS_DEBUGGABLE private val DEFAULT_TRANSITION_ANIMATOR = TransitionAnimator(TIMINGS, INTERPOLATORS) private val DEFAULT_TRANSITION_ANIMATOR = TransitionAnimator(TIMINGS, INTERPOLATORS) private val DEFAULT_DIALOG_TO_APP_ANIMATOR = private val DEFAULT_DIALOG_TO_APP_ANIMATOR = Loading @@ -113,13 +113,13 @@ class ActivityLaunchAnimator( private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f) private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f) /** The time we wait before timing out the remote animation after starting the intent. */ /** The time we wait before timing out the remote animation after starting the intent. */ private const val LAUNCH_TIMEOUT = 1_000L private const val TRANSITION_TIMEOUT = 1_000L /** /** * The time we wait before we Log.wtf because the remote animation was neither started or * The time we wait before we Log.wtf because the remote animation was neither started or * cancelled by WM. * cancelled by WM. */ */ private const val LONG_LAUNCH_TIMEOUT = 5_000L private const val LONG_TRANSITION_TIMEOUT = 5_000L } } /** /** Loading @@ -134,20 +134,20 @@ class ActivityLaunchAnimator( /** Top-level listener that can be used to notify all registered [listeners]. */ /** Top-level listener that can be used to notify all registered [listeners]. */ private val lifecycleListener = private val lifecycleListener = object : Listener { object : Listener { override fun onLaunchAnimationStart() { override fun onTransitionAnimationStart() { listeners.forEach { it.onLaunchAnimationStart() } listeners.forEach { it.onTransitionAnimationStart() } } } override fun onLaunchAnimationEnd() { override fun onTransitionAnimationEnd() { listeners.forEach { it.onLaunchAnimationEnd() } listeners.forEach { it.onTransitionAnimationEnd() } } } override fun onLaunchAnimationProgress(linearProgress: Float) { override fun onTransitionAnimationProgress(linearProgress: Float) { listeners.forEach { it.onLaunchAnimationProgress(linearProgress) } listeners.forEach { it.onTransitionAnimationProgress(linearProgress) } } } override fun onLaunchAnimationCancelled() { override fun onTransitionAnimationCancelled() { listeners.forEach { it.onLaunchAnimationCancelled() } listeners.forEach { it.onTransitionAnimationCancelled() } } } } } Loading Loading @@ -188,7 +188,7 @@ class ActivityLaunchAnimator( val callback = val callback = this.callback this.callback ?: throw IllegalStateException( ?: throw IllegalStateException( "ActivityLaunchAnimator.callback must be set before using this animator" "ActivityTransitionAnimator.callback must be set before using this animator" ) ) val runner = createRunner(controller) val runner = createRunner(controller) val runnerDelegate = runner.delegate!! val runnerDelegate = runner.delegate!! Loading Loading @@ -260,7 +260,7 @@ class ActivityLaunchAnimator( callOnIntentStartedOnMainThread(willAnimate) callOnIntentStartedOnMainThread(willAnimate) } } } else { } else { if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onIntentStarted(willAnimate=$willAnimate) " + "Calling controller.onIntentStarted(willAnimate=$willAnimate) " + Loading Loading @@ -293,7 +293,7 @@ class ActivityLaunchAnimator( } } } } /** Add a [Listener] that can listen to launch animations. */ /** Add a [Listener] that can listen to transition animations. */ fun addListener(listener: Listener) { fun addListener(listener: Listener) { listeners.add(listener) listeners.add(listener) } } Loading Loading @@ -340,24 +340,24 @@ class ActivityLaunchAnimator( } } interface Listener { interface Listener { /** Called when an activity launch animation started. */ /** Called when an activity transition animation started. */ fun onLaunchAnimationStart() {} fun onTransitionAnimationStart() {} /** /** * Called when an activity launch animation is finished. This will be called if and only if * Called when an activity transition animation is finished. This will be called if and only * [onLaunchAnimationStart] was called earlier. * if [onTransitionAnimationStart] was called earlier. */ */ fun onLaunchAnimationEnd() {} fun onTransitionAnimationEnd() {} /** /** * The animation was cancelled. Note that [onLaunchAnimationEnd] will still be called after * The animation was cancelled. Note that [onTransitionAnimationEnd] will still be called * this if the animation was already started, i.e. if [onLaunchAnimationStart] was called * after this if the animation was already started, i.e. if [onTransitionAnimationStart] was * before the cancellation. * called before the cancellation. */ */ fun onLaunchAnimationCancelled() {} fun onTransitionAnimationCancelled() {} /** Called when an activity launch animation made progress. */ /** Called when an activity transition animation made progress. */ fun onLaunchAnimationProgress(linearProgress: Float) {} fun onTransitionAnimationProgress(linearProgress: Float) {} } } /** /** Loading @@ -383,9 +383,10 @@ class ActivityLaunchAnimator( // issues. // issues. if (view !is LaunchableView) { if (view !is LaunchableView) { throw IllegalArgumentException( throw IllegalArgumentException( "An ActivityLaunchAnimator.Controller was created from a View that does " + "An ActivityTransitionAnimator.Controller was created from a View that " + "not implement LaunchableView. This can lead to subtle bugs where the" + "does not implement LaunchableView. This can lead to subtle bugs " + " visibility of the View we are launching from is not what we expected." "where the visibility of the View we are launching from is not what " + "we expected." ) ) } } Loading @@ -411,11 +412,11 @@ class ActivityLaunchAnimator( get() = false get() = false /** /** * Whether the expandable controller by this [Controller] is below the launching window that * Whether the expandable controller by this [Controller] is below the window that is going * is going to be animated. * to be animated. * * * This should be `false` when launching an app from the shade or status bar, given that * This should be `false` when animating an app from or to the shade or status bar, given * they are drawn above all apps. This is usually `true` when using this launcher in a * that they are drawn above all apps. This is usually `true` when using this animator in a * normal app or a launcher, that are drawn below the animating activity/window. * normal app or a launcher, that are drawn below the animating activity/window. */ */ val isBelowAnimatingWindow: Boolean val isBelowAnimatingWindow: Boolean Loading @@ -432,10 +433,11 @@ class ActivityLaunchAnimator( * after this if the animation was already started, i.e. if [onTransitionAnimationStart] was * after this if the animation was already started, i.e. if [onTransitionAnimationStart] was * called before the cancellation. * called before the cancellation. * * * If this launch animation affected the occlusion state of the keyguard, WM will provide us * If this transition animation affected the occlusion state of the keyguard, WM will * with [newKeyguardOccludedState] so that we can set the occluded state appropriately. * provide us with [newKeyguardOccludedState] so that we can set the occluded state * appropriately. */ */ fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {} fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {} } } /** /** Loading @@ -449,24 +451,24 @@ class ActivityLaunchAnimator( ) : Listener { ) : Listener { var cancelled = false var cancelled = false override fun onLaunchAnimationStart() { override fun onTransitionAnimationStart() { delegate?.onLaunchAnimationStart() delegate?.onTransitionAnimationStart() } } override fun onLaunchAnimationProgress(linearProgress: Float) { override fun onTransitionAnimationProgress(linearProgress: Float) { delegate?.onLaunchAnimationProgress(linearProgress) delegate?.onTransitionAnimationProgress(linearProgress) } } override fun onLaunchAnimationEnd() { override fun onTransitionAnimationEnd() { delegate?.onLaunchAnimationEnd() delegate?.onTransitionAnimationEnd() if (!cancelled) { if (!cancelled) { onAnimationComplete.invoke() onAnimationComplete.invoke() } } } } override fun onLaunchAnimationCancelled() { override fun onTransitionAnimationCancelled() { cancelled = true cancelled = true delegate?.onLaunchAnimationCancelled() delegate?.onTransitionAnimationCancelled() onAnimationComplete.invoke() onAnimationComplete.invoke() } } } } Loading @@ -475,7 +477,7 @@ class ActivityLaunchAnimator( inner class Runner( inner class Runner( controller: Controller, controller: Controller, callback: Callback, callback: Callback, /** The animator to use to animate the window launch. */ /** The animator to use to animate the window transition. */ transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, /** Listener for animation lifecycle events. */ /** Listener for animation lifecycle events. */ listener: Listener? = null listener: Listener? = null Loading Loading @@ -543,7 +545,7 @@ class ActivityLaunchAnimator( private val callback: Callback, private val callback: Callback, /** Listener for animation lifecycle events. */ /** Listener for animation lifecycle events. */ private val listener: Listener? = null, private val listener: Listener? = null, /** The animator to use to animate the window launch. */ /** The animator to use to animate the window transition. */ private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, private val transitionAnimator: TransitionAnimator = DEFAULT_TRANSITION_ANIMATOR, /** /** Loading Loading @@ -574,8 +576,8 @@ class ActivityLaunchAnimator( private var animation: TransitionAnimator.Animation? = null private var animation: TransitionAnimator.Animation? = null /** /** * A timeout to cancel the launch animation if the remote animation is not started or * A timeout to cancel the transition animation if the remote animation is not started or * cancelled within [LAUNCH_TIMEOUT] milliseconds after the intent was started. * cancelled within [TRANSITION_TIMEOUT] milliseconds after the intent was started. * * * Note that this is important to keep this a Runnable (and not a Kotlin lambda), otherwise * Note that this is important to keep this a Runnable (and not a Kotlin lambda), otherwise * it will be automatically converted when posted and we wouldn't be able to remove it after * it will be automatically converted when posted and we wouldn't be able to remove it after Loading @@ -585,21 +587,22 @@ class ActivityLaunchAnimator( /** /** * A long timeout to Log.wtf (signaling a bug in WM) when the remote animation wasn't * A long timeout to Log.wtf (signaling a bug in WM) when the remote animation wasn't * started or cancelled within [LONG_LAUNCH_TIMEOUT] milliseconds after the intent was * started or cancelled within [LONG_TRANSITION_TIMEOUT] milliseconds after the intent was * started. * started. */ */ private var onLongTimeout = Runnable { private var onLongTimeout = Runnable { Log.wtf( Log.wtf( TAG, TAG, "The remote animation was neither cancelled or started within $LONG_LAUNCH_TIMEOUT" "The remote animation was neither cancelled or started within " + "$LONG_TRANSITION_TIMEOUT" ) ) } } @UiThread @UiThread internal fun postTimeouts() { internal fun postTimeouts() { if (timeoutHandler != null) { if (timeoutHandler != null) { timeoutHandler.postDelayed(onTimeout, LAUNCH_TIMEOUT) timeoutHandler.postDelayed(onTimeout, TRANSITION_TIMEOUT) timeoutHandler.postDelayed(onLongTimeout, LONG_LAUNCH_TIMEOUT) timeoutHandler.postDelayed(onLongTimeout, LONG_TRANSITION_TIMEOUT) } } } } Loading Loading @@ -670,14 +673,14 @@ class ActivityLaunchAnimator( Log.i(TAG, "Aborting the animation as no window is opening") Log.i(TAG, "Aborting the animation as no window is opening") iCallback?.invoke() iCallback?.invoke() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationCancelled() [no window opening]" "Calling controller.onTransitionAnimationCancelled() [no window opening]" ) ) } } controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() listener?.onLaunchAnimationCancelled() listener?.onTransitionAnimationCancelled() return return } } Loading Loading @@ -720,27 +723,29 @@ class ActivityLaunchAnimator( val controller = val controller = object : Controller by delegate { object : Controller by delegate { override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { listener?.onLaunchAnimationStart() listener?.onTransitionAnimationStart() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationStart(isExpandingFullyAbove=" + "Calling controller.onTransitionAnimationStart(" + "$isExpandingFullyAbove) [controller=$delegate]" "isExpandingFullyAbove=$isExpandingFullyAbove) " + "[controller=$delegate]" ) ) } } delegate.onTransitionAnimationStart(isExpandingFullyAbove) delegate.onTransitionAnimationStart(isExpandingFullyAbove) } } override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { listener?.onLaunchAnimationEnd() listener?.onTransitionAnimationEnd() iCallback?.invoke() iCallback?.invoke() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationEnd(isExpandingFullyAbove=" + "Calling controller.onTransitionAnimationEnd(" + "$isExpandingFullyAbove) [controller=$delegate]" "isExpandingFullyAbove=$isExpandingFullyAbove) " + "[controller=$delegate]" ) ) } } delegate.onTransitionAnimationEnd(isExpandingFullyAbove) delegate.onTransitionAnimationEnd(isExpandingFullyAbove) Loading @@ -758,7 +763,7 @@ class ActivityLaunchAnimator( } } navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) } navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) } listener?.onLaunchAnimationProgress(linearProgress) listener?.onTransitionAnimationProgress(linearProgress) delegate.onTransitionAnimationProgress(state, progress, linearProgress) delegate.onTransitionAnimationProgress(state, progress, linearProgress) } } } } Loading Loading @@ -904,7 +909,7 @@ class ActivityLaunchAnimator( } } private fun onAnimationTimedOut() { private fun onAnimationTimedOut() { // The remote animation was cancelled by WM, so we already cancelled the launch // The remote animation was cancelled by WM, so we already cancelled the transition // animation. // animation. if (cancelled) { if (cancelled) { return return Loading @@ -913,18 +918,21 @@ class ActivityLaunchAnimator( Log.w(TAG, "Remote animation timed out") Log.w(TAG, "Remote animation timed out") timedOut = true timedOut = true if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d(TAG, "Calling controller.onLaunchAnimationCancelled() [animation timed out]") Log.d( TAG, "Calling controller.onTransitionAnimationCancelled() [animation timed out]" ) } } controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() listener?.onLaunchAnimationCancelled() listener?.onTransitionAnimationCancelled() } } @UiThread @UiThread override fun onAnimationCancelled() { override fun onAnimationCancelled() { removeTimeouts() removeTimeouts() // The short timeout happened, so we already cancelled the launch animation. // The short timeout happened, so we already cancelled the transition animation. if (timedOut) { if (timedOut) { return return } } Loading @@ -934,14 +942,15 @@ class ActivityLaunchAnimator( animation?.cancel() animation?.cancel() if (DEBUG_LAUNCH_ANIMATION) { if (DEBUG_TRANSITION_ANIMATION) { Log.d( Log.d( TAG, TAG, "Calling controller.onLaunchAnimationCancelled() [remote animation cancelled]", "Calling controller.onTransitionAnimationCancelled() [remote animation " + "cancelled]", ) ) } } controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() listener?.onLaunchAnimationCancelled() listener?.onTransitionAnimationCancelled() } } private fun IRemoteAnimationFinishedCallback.invoke() { private fun IRemoteAnimationFinishedCallback.invoke() { Loading
packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt +3 −3 Original line number Original line Diff line number Diff line Loading @@ -17,10 +17,10 @@ package com.android.systemui.animation package com.android.systemui.animation /** /** * A base class to easily create an implementation of [ActivityLaunchAnimator.Controller] which * A base class to easily create an implementation of [ActivityTransitionAnimator.Controller] which * delegates most of its call to [delegate]. This is mostly useful for Java code which can't easily * delegates most of its call to [delegate]. This is mostly useful for Java code which can't easily * create such a delegated class. * create such a delegated class. */ */ open class DelegateLaunchAnimatorController( open class DelegateLaunchAnimatorController( protected val delegate: ActivityLaunchAnimator.Controller protected val delegate: ActivityTransitionAnimator.Controller ) : ActivityLaunchAnimator.Controller by delegate ) : ActivityTransitionAnimator.Controller by delegate
packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt +15 −14 Original line number Original line Diff line number Diff line Loading @@ -62,13 +62,14 @@ constructor( private val isForTesting: Boolean = false, private val isForTesting: Boolean = false, ) { ) { private companion object { private companion object { private val TIMINGS = ActivityLaunchAnimator.TIMINGS private val TIMINGS = ActivityTransitionAnimator.TIMINGS // We use the same interpolator for X and Y axis to make sure the dialog does not move out // We use the same interpolator for X and Y axis to make sure the dialog does not move out // of the screen bounds during the animation. // of the screen bounds during the animation. private val INTERPOLATORS = private val INTERPOLATORS = ActivityLaunchAnimator.INTERPOLATORS.copy( ActivityTransitionAnimator.INTERPOLATORS.copy( positionXInterpolator = ActivityLaunchAnimator.INTERPOLATORS.positionInterpolator positionXInterpolator = ActivityTransitionAnimator.INTERPOLATORS.positionInterpolator ) ) } } Loading Loading @@ -319,9 +320,9 @@ constructor( } } /** /** * Create an [ActivityLaunchAnimator.Controller] that can be used to launch an activity from the * Create an [ActivityTransitionAnimator.Controller] that can be used to launch an activity from * dialog that contains [View]. Note that the dialog must have been shown using this animator, * the dialog that contains [View]. Note that the dialog must have been shown using this * otherwise this method will return null. * animator, otherwise this method will return null. * * * The returned controller will take care of dismissing the dialog at the right time after the * The returned controller will take care of dismissing the dialog at the right time after the * activity started, when the dialog to app animation is done (or when it is cancelled). If this * activity started, when the dialog to app animation is done (or when it is cancelled). If this Loading @@ -333,7 +334,7 @@ constructor( fun createActivityLaunchController( fun createActivityLaunchController( view: View, view: View, cujType: Int? = null, cujType: Int? = null, ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { val animatedDialog = val animatedDialog = openedDialogs.firstOrNull { openedDialogs.firstOrNull { it.dialog.window?.decorView?.viewRootImpl == view.viewRootImpl it.dialog.window?.decorView?.viewRootImpl == view.viewRootImpl Loading @@ -343,7 +344,7 @@ constructor( } } /** /** * Create an [ActivityLaunchAnimator.Controller] that can be used to launch an activity from * Create an [ActivityTransitionAnimator.Controller] that can be used to launch an activity from * [dialog]. Note that the dialog must have been shown using this animator, otherwise this * [dialog]. Note that the dialog must have been shown using this animator, otherwise this * method will return null. * method will return null. * * Loading @@ -357,7 +358,7 @@ constructor( fun createActivityLaunchController( fun createActivityLaunchController( dialog: Dialog, dialog: Dialog, cujType: Int? = null, cujType: Int? = null, ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { val animatedDialog = openedDialogs.firstOrNull { it.dialog == dialog } ?: return null val animatedDialog = openedDialogs.firstOrNull { it.dialog == dialog } ?: return null return createActivityLaunchController(animatedDialog, cujType) return createActivityLaunchController(animatedDialog, cujType) } } Loading @@ -365,7 +366,7 @@ constructor( private fun createActivityLaunchController( private fun createActivityLaunchController( animatedDialog: AnimatedDialog, animatedDialog: AnimatedDialog, cujType: Int? = null cujType: Int? = null ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { // At this point, we know that the intent of the caller is to dismiss the dialog to show // At this point, we know that the intent of the caller is to dismiss the dialog to show // an app, so we disable the exit animation into the source because we will never want to // an app, so we disable the exit animation into the source because we will never want to // run it anyways. // run it anyways. Loading @@ -384,12 +385,12 @@ constructor( val dialogContentWithBackground = animatedDialog.dialogContentWithBackground ?: return null val dialogContentWithBackground = animatedDialog.dialogContentWithBackground ?: return null val controller = val controller = ActivityLaunchAnimator.Controller.fromView(dialogContentWithBackground, cujType) ActivityTransitionAnimator.Controller.fromView(dialogContentWithBackground, cujType) ?: return null ?: return null // Wrap the controller into one that will instantly dismiss the dialog when the animation is // Wrap the controller into one that will instantly dismiss the dialog when the animation is // done or dismiss it normally (fading it out) if the animation is cancelled. // done or dismiss it normally (fading it out) if the animation is cancelled. return object : ActivityLaunchAnimator.Controller by controller { return object : ActivityTransitionAnimator.Controller by controller { override val isDialogLaunch = true override val isDialogLaunch = true override fun onIntentStarted(willAnimate: Boolean) { override fun onIntentStarted(willAnimate: Boolean) { Loading @@ -400,8 +401,8 @@ constructor( } } } } override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) { override fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean?) { controller.onLaunchAnimationCancelled() controller.onTransitionAnimationCancelled() enableDialogDismiss() enableDialogDismiss() dialog.dismiss() dialog.dismiss() } } Loading
packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt +6 −6 Original line number Original line Diff line number Diff line Loading @@ -21,14 +21,14 @@ import android.view.View /** A piece of UI that can be expanded into a Dialog or an Activity. */ /** A piece of UI that can be expanded into a Dialog or an Activity. */ interface Expandable { interface Expandable { /** /** * Create an [ActivityLaunchAnimator.Controller] that can be used to expand this [Expandable] * Create an [ActivityTransitionAnimator.Controller] that can be used to expand this * into an Activity, or return `null` if this [Expandable] should not be animated (e.g. if it is * [Expandable] into an Activity, or return `null` if this [Expandable] should not be animated * currently not attached or visible). * (e.g. if it is currently not attached or visible). * * * @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor] * @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor] * associated to the launch that will use this controller. * associated to the launch that will use this controller. */ */ fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller? fun activityLaunchController(cujType: Int? = null): ActivityTransitionAnimator.Controller? /** /** * Create a [DialogLaunchAnimator.Controller] that can be used to expand this [Expandable] into * Create a [DialogLaunchAnimator.Controller] that can be used to expand this [Expandable] into Loading @@ -49,8 +49,8 @@ interface Expandable { return object : Expandable { return object : Expandable { override fun activityLaunchController( override fun activityLaunchController( cujType: Int?, cujType: Int?, ): ActivityLaunchAnimator.Controller? { ): ActivityTransitionAnimator.Controller? { return ActivityLaunchAnimator.Controller.fromView(view, cujType) return ActivityTransitionAnimator.Controller.fromView(view, cujType) } } override fun dialogLaunchController( override fun dialogLaunchController( Loading
packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt +5 −5 Original line number Original line Diff line number Diff line Loading @@ -42,15 +42,15 @@ import kotlin.math.roundToInt private const val TAG = "GhostedViewLaunchAnimatorController" private const val TAG = "GhostedViewLaunchAnimatorController" /** /** * A base implementation of [ActivityLaunchAnimator.Controller] which creates a [ghost][GhostView] * A base implementation of [ActivityTransitionAnimator.Controller] which creates a * of [ghostedView] as well as an expandable background view, which are drawn and animated instead * [ghost][GhostView] of [ghostedView] as well as an expandable background view, which are drawn and * of the ghosted view. * animated instead of the ghosted view. * * * Important: [ghostedView] must be attached to a [ViewGroup] when calling this function and during * Important: [ghostedView] must be attached to a [ViewGroup] when calling this function and during * the animation. It must also implement [LaunchableView], otherwise an exception will be thrown * the animation. It must also implement [LaunchableView], otherwise an exception will be thrown * during this controller instantiation. * during this controller instantiation. * * * Note: Avoid instantiating this directly and call [ActivityLaunchAnimator.Controller.fromView] * Note: Avoid instantiating this directly and call [ActivityTransitionAnimator.Controller.fromView] * whenever possible instead. * whenever possible instead. */ */ open class GhostedViewLaunchAnimatorController open class GhostedViewLaunchAnimatorController Loading @@ -63,7 +63,7 @@ constructor( private val cujType: Int? = null, private val cujType: Int? = null, private var interactionJankMonitor: InteractionJankMonitor = private var interactionJankMonitor: InteractionJankMonitor = InteractionJankMonitor.getInstance(), InteractionJankMonitor.getInstance(), ) : ActivityLaunchAnimator.Controller { ) : ActivityTransitionAnimator.Controller { /** The container to which we will add the ghost view and expanding background. */ /** The container to which we will add the ghost view and expanding background. */ override var transitionContainer = ghostedView.rootView as ViewGroup override var transitionContainer = ghostedView.rootView as ViewGroup Loading