diff options
2 files changed, 106 insertions, 75 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt index c14ee6208176..9d0b095ad4cc 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt @@ -55,6 +55,7 @@ import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils import com.android.systemui.Flags.activityTransitionUseLargestWindow import com.android.systemui.Flags.translucentOccludingActivityFix +import com.android.systemui.animation.TransitionAnimator.Companion.toTransitionState import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary import com.android.wm.shell.shared.IShellTransitions import com.android.wm.shell.shared.ShellTransitions @@ -130,7 +131,7 @@ constructor( contentBeforeFadeOutDelay = 0L, contentBeforeFadeOutDuration = 150L, contentAfterFadeInDelay = 150L, - contentAfterFadeInDuration = 183L + contentAfterFadeInDuration = 183L, ) /** @@ -147,7 +148,7 @@ constructor( positionInterpolator = Interpolators.EMPHASIZED, positionXInterpolator = Interpolators.EMPHASIZED_COMPLEMENT, contentBeforeFadeOutInterpolator = Interpolators.LINEAR_OUT_SLOW_IN, - contentAfterFadeInInterpolator = PathInterpolator(0f, 0f, 0.6f, 1f) + contentAfterFadeInInterpolator = PathInterpolator(0f, 0f, 0.6f, 1f), ) // TODO(b/288507023): Remove this flag. @@ -238,7 +239,7 @@ constructor( animate: Boolean = true, packageName: String? = null, showOverLockscreen: Boolean = false, - intentStarter: (RemoteAnimationAdapter?) -> Int + intentStarter: (RemoteAnimationAdapter?) -> Int, ) { if (controller == null || !animate) { Log.i(TAG, "Starting intent with no animation") @@ -263,7 +264,7 @@ constructor( RemoteAnimationAdapter( runner, TIMINGS.totalDuration, - TIMINGS.totalDuration - 150 /* statusBarTransitionDelay */ + TIMINGS.totalDuration - 150, /* statusBarTransitionDelay */ ) } else { null @@ -277,7 +278,7 @@ constructor( .registerRemoteAnimationForNextActivityStart( packageName, animationAdapter, - null /* launchCookie */ + null, /* launchCookie */ ) } catch (e: RemoteException) { Log.w(TAG, "Unable to register the remote animation", e) @@ -301,7 +302,7 @@ constructor( Log.i( TAG, "launchResult=$launchResult willAnimate=$willAnimate " + - "hideKeyguardWithAnimation=$hideKeyguardWithAnimation" + "hideKeyguardWithAnimation=$hideKeyguardWithAnimation", ) controller.callOnIntentStartedOnMainThread(willAnimate) @@ -328,7 +329,7 @@ constructor( Log.d( TAG, "Calling controller.onIntentStarted(willAnimate=$willAnimate) " + - "[controller=$this]" + "[controller=$this]", ) } this.onIntentStarted(willAnimate) @@ -350,7 +351,7 @@ constructor( animate: Boolean = true, packageName: String? = null, showOverLockscreen: Boolean = false, - intentStarter: PendingIntentStarter + intentStarter: PendingIntentStarter, ) { startIntentWithAnimation(controller, animate, packageName, showOverLockscreen) { intentStarter.startPendingIntent(it) @@ -366,7 +367,7 @@ constructor( */ private fun registerEphemeralReturnAnimation( launchController: Controller, - transitionRegister: TransitionRegister? + transitionRegister: TransitionRegister?, ) { if (!returnAnimationFrameworkLibrary()) return @@ -410,7 +411,7 @@ constructor( val transition = RemoteTransition( RemoteAnimationRunnerCompat.wrap(returnRunner), - "${launchController.transitionCookie}_returnTransition" + "${launchController.transitionCookie}_returnTransition", ) transitionRegister?.register(filter, transition) @@ -508,7 +509,7 @@ constructor( cujType: Int? = null, cookie: TransitionCookie? = null, component: ComponentName? = null, - returnCujType: Int? = null + returnCujType: Int? = null, ): Controller? { // Make sure the View we launch from implements LaunchableView to avoid visibility // issues. @@ -525,7 +526,7 @@ constructor( Log.e( TAG, "Skipping animation as view $view is not attached to a ViewGroup", - Exception() + Exception(), ) return null } @@ -535,7 +536,7 @@ constructor( cujType, cookie, component, - returnCujType + returnCujType, ) } } @@ -646,7 +647,7 @@ constructor( val launchRemoteTransition = RemoteTransition( RemoteAnimationRunnerCompat.wrap(createRunner(controller)), - "${cookie}_launchTransition" + "${cookie}_launchTransition", ) transitionRegister.register(launchFilter, launchRemoteTransition) @@ -668,7 +669,7 @@ constructor( val returnRemoteTransition = RemoteTransition( RemoteAnimationRunnerCompat.wrap(createRunner(returnController)), - "${cookie}_returnTransition" + "${cookie}_returnTransition", ) transitionRegister.register(returnFilter, returnRemoteTransition) @@ -690,7 +691,7 @@ constructor( @VisibleForTesting inner class DelegatingAnimationCompletionListener( private val delegate: Listener?, - private val onAnimationComplete: () -> Unit + private val onAnimationComplete: () -> Unit, ) : Listener { var cancelled = false @@ -723,7 +724,7 @@ constructor( /** The animator to use to animate the window transition. */ transitionAnimator: TransitionAnimator, /** Listener for animation lifecycle events. */ - listener: Listener? = null + listener: Listener? = null, ) : IRemoteAnimationRunner.Stub() { // This is being passed across IPC boundaries and cycles (through PendingIntentRecords, // etc.) are possible. So we need to make sure we drop any references that might @@ -748,7 +749,7 @@ constructor( apps: Array<out RemoteAnimationTarget>?, wallpapers: Array<out RemoteAnimationTarget>?, nonApps: Array<out RemoteAnimationTarget>?, - finishedCallback: IRemoteAnimationFinishedCallback? + finishedCallback: IRemoteAnimationFinishedCallback?, ) { val delegate = delegate mainExecutor.execute { @@ -838,7 +839,7 @@ constructor( Log.wtf( TAG, "The remote animation was neither cancelled or started within " + - "$LONG_TRANSITION_TIMEOUT" + "$LONG_TRANSITION_TIMEOUT", ) } @@ -869,7 +870,7 @@ constructor( apps: Array<out RemoteAnimationTarget>?, wallpapers: Array<out RemoteAnimationTarget>?, nonApps: Array<out RemoteAnimationTarget>?, - callback: IRemoteAnimationFinishedCallback? + callback: IRemoteAnimationFinishedCallback?, ) { removeTimeouts() @@ -894,7 +895,7 @@ constructor( if (DEBUG_TRANSITION_ANIMATION) { Log.d( TAG, - "Calling controller.onTransitionAnimationCancelled() [no window opening]" + "Calling controller.onTransitionAnimationCancelled() [no window opening]", ) } controller.onTransitionAnimationCancelled() @@ -974,7 +975,7 @@ constructor( private fun startAnimation( window: RemoteAnimationTarget, navigationBar: RemoteAnimationTarget?, - iCallback: IRemoteAnimationFinishedCallback? + iCallback: IRemoteAnimationFinishedCallback?, ) { if (TransitionAnimator.DEBUG) { Log.d(TAG, "Remote animation started") @@ -983,12 +984,28 @@ constructor( val windowBounds = window.screenSpaceBounds val endState = if (controller.isLaunching) { - TransitionAnimator.State( - top = windowBounds.top, - bottom = windowBounds.bottom, - left = windowBounds.left, - right = windowBounds.right - ) + controller.windowAnimatorState?.toTransitionState() + ?: TransitionAnimator.State( + top = windowBounds.top, + bottom = windowBounds.bottom, + left = windowBounds.left, + right = windowBounds.right, + ) + .apply { + // TODO(b/184121838): We should somehow get the top and bottom + // radius of the window instead of recomputing isExpandingFullyAbove + // here. + getWindowRadius( + transitionAnimator.isExpandingFullyAbove( + controller.transitionContainer, + this, + ) + ) + .let { + topCornerRadius = it + bottomCornerRadius = it + } + } } else { controller.createAnimatorState() } @@ -1000,15 +1017,8 @@ constructor( ?: window.backgroundColor } - // TODO(b/184121838): We should somehow get the top and bottom radius of the window - // instead of recomputing isExpandingFullyAbove here. val isExpandingFullyAbove = transitionAnimator.isExpandingFullyAbove(controller.transitionContainer, endState) - if (controller.isLaunching) { - val endRadius = getWindowRadius(isExpandingFullyAbove) - endState.topCornerRadius = endRadius - endState.bottomCornerRadius = endRadius - } // We animate the opening window and delegate the view expansion to [this.controller]. val delegate = this.controller @@ -1016,15 +1026,17 @@ constructor( object : Controller by delegate { override fun createAnimatorState(): TransitionAnimator.State { if (isLaunching) return delegate.createAnimatorState() - val windowRadius = getWindowRadius(isExpandingFullyAbove) - return TransitionAnimator.State( - top = windowBounds.top, - bottom = windowBounds.bottom, - left = windowBounds.left, - right = windowBounds.right, - topCornerRadius = windowRadius, - bottomCornerRadius = windowRadius - ) + return delegate.windowAnimatorState?.toTransitionState() + ?: getWindowRadius(isExpandingFullyAbove).let { + TransitionAnimator.State( + top = windowBounds.top, + bottom = windowBounds.bottom, + left = windowBounds.left, + right = windowBounds.right, + topCornerRadius = it, + bottomCornerRadius = it, + ) + } } override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { @@ -1035,7 +1047,7 @@ constructor( TAG, "Calling controller.onTransitionAnimationStart(" + "isExpandingFullyAbove=$isExpandingFullyAbove) " + - "[controller=$delegate]" + "[controller=$delegate]", ) } delegate.onTransitionAnimationStart(isExpandingFullyAbove) @@ -1050,7 +1062,7 @@ constructor( TAG, "Calling controller.onTransitionAnimationEnd(" + "isExpandingFullyAbove=$isExpandingFullyAbove) " + - "[controller=$delegate]" + "[controller=$delegate]", ) } delegate.onTransitionAnimationEnd(isExpandingFullyAbove) @@ -1059,7 +1071,7 @@ constructor( override fun onTransitionAnimationProgress( state: TransitionAnimator.State, progress: Float, - linearProgress: Float + linearProgress: Float, ) { applyStateToWindow(window, state, linearProgress) navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) } @@ -1135,7 +1147,7 @@ constructor( windowCropF.left.roundToInt(), windowCropF.top.roundToInt(), windowCropF.right.roundToInt(), - windowCropF.bottom.roundToInt() + windowCropF.bottom.roundToInt(), ) val windowAnimationDelay = @@ -1155,7 +1167,7 @@ constructor( TIMINGS, linearProgress, windowAnimationDelay, - windowAnimationDuration + windowAnimationDuration, ) // The alpha of the opening window. If it opens above the expandable, then it should @@ -1198,7 +1210,7 @@ constructor( private fun applyStateToNavigationBar( navigationBar: RemoteAnimationTarget, state: TransitionAnimator.State, - linearProgress: Float + linearProgress: Float, ) { if (transactionApplierView.viewRootImpl == null || !navigationBar.leash.isValid) { // Don't apply any transaction if the view root we synchronize with was detached or @@ -1212,7 +1224,7 @@ constructor( TIMINGS, linearProgress, ANIMATION_DELAY_NAV_FADE_IN, - ANIMATION_DURATION_NAV_FADE_OUT + ANIMATION_DURATION_NAV_FADE_OUT, ) val params = SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(navigationBar.leash) @@ -1220,7 +1232,7 @@ constructor( matrix.reset() matrix.setTranslate( 0f, - (state.top - navigationBar.sourceContainerBounds.top).toFloat() + (state.top - navigationBar.sourceContainerBounds.top).toFloat(), ) windowCrop.set(state.left, 0, state.right, state.height) params @@ -1234,7 +1246,7 @@ constructor( TIMINGS, linearProgress, 0, - ANIMATION_DURATION_NAV_FADE_OUT + ANIMATION_DURATION_NAV_FADE_OUT, ) params.withAlpha(1f - NAV_FADE_OUT_INTERPOLATOR.getInterpolation(fadeOutProgress)) } @@ -1255,7 +1267,7 @@ constructor( if (DEBUG_TRANSITION_ANIMATION) { Log.d( TAG, - "Calling controller.onTransitionAnimationCancelled() [animation timed out]" + "Calling controller.onTransitionAnimationCancelled() [animation timed out]", ) } controller.onTransitionAnimationCancelled() @@ -1329,10 +1341,7 @@ constructor( } /** Register [remoteTransition] with WM Shell using the given [filter]. */ - internal fun register( - filter: TransitionFilter, - remoteTransition: RemoteTransition, - ) { + internal fun register(filter: TransitionFilter, remoteTransition: RemoteTransition) { shellTransitions?.registerRemote(filter, remoteTransition) iShellTransitions?.registerRemote(filter, remoteTransition) } diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt index 8e824e60d449..fc4cf1d1e21e 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt @@ -28,6 +28,7 @@ import android.util.MathUtils import android.view.View import android.view.ViewGroup import android.view.animation.Interpolator +import android.window.WindowAnimationState import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators.LINEAR import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary @@ -56,12 +57,12 @@ class TransitionAnimator( timings: Timings, linearProgress: Float, delay: Long, - duration: Long + duration: Long, ): Float { return MathUtils.constrain( (linearProgress * timings.totalDuration - delay) / duration, 0.0f, - 1.0f + 1.0f, ) } @@ -71,6 +72,18 @@ class TransitionAnimator( "disabled" } } + + internal fun WindowAnimationState.toTransitionState() = + State().also { + bounds?.let { b -> + it.top = b.top.roundToInt() + it.left = b.left.roundToInt() + it.bottom = b.bottom.roundToInt() + it.right = b.right.roundToInt() + } + it.bottomCornerRadius = (bottomLeftRadius + bottomRightRadius) / 2 + it.topCornerRadius = (topLeftRadius + topRightRadius) / 2 + } } private val transitionContainerLocation = IntArray(2) @@ -117,6 +130,15 @@ class TransitionAnimator( get() = null /** + * Window state for the animation. If [isLaunching], it would correspond to the end state + * otherwise the start state. + * + * If null, the state is inferred from the window targets + */ + val windowAnimatorState: WindowAnimationState? + get() = null + + /** * Return the [State] of the view that will be animated. We will animate from this state to * the final window state. * @@ -151,7 +173,7 @@ class TransitionAnimator( var left: Int = 0, var right: Int = 0, var topCornerRadius: Float = 0f, - var bottomCornerRadius: Float = 0f + var bottomCornerRadius: Float = 0f, ) { private val startTop = top @@ -197,7 +219,7 @@ class TransitionAnimator( val contentAfterFadeInDelay: Long, /** The duration of the expanded content fade in. */ - val contentAfterFadeInDuration: Long + val contentAfterFadeInDuration: Long, ) /** The interpolators used by this animator. */ @@ -215,7 +237,7 @@ class TransitionAnimator( val contentBeforeFadeOutInterpolator: Interpolator, /** The interpolator used when fading in the expanded content. */ - val contentAfterFadeInInterpolator: Interpolator + val contentAfterFadeInInterpolator: Interpolator, ) /** @@ -254,7 +276,7 @@ class TransitionAnimator( endState, windowBackgroundLayer, fadeWindowBackgroundLayer, - drawHole + drawHole, ) animator.start() @@ -271,7 +293,7 @@ class TransitionAnimator( endState: State, windowBackgroundLayer: GradientDrawable, fadeWindowBackgroundLayer: Boolean = true, - drawHole: Boolean = false + drawHole: Boolean = false, ): ValueAnimator { val state = controller.createAnimatorState() @@ -399,14 +421,14 @@ class TransitionAnimator( timings, linearProgress, timings.contentBeforeFadeOutDelay, - timings.contentBeforeFadeOutDuration + timings.contentBeforeFadeOutDuration, ) < 1 } else { getProgress( timings, linearProgress, timings.contentAfterFadeInDelay, - timings.contentAfterFadeInDuration + timings.contentAfterFadeInDuration, ) > 0 } @@ -427,7 +449,7 @@ class TransitionAnimator( ViewRootSync.synchronizeNextDraw( transitionContainer, openingWindowSyncView, - then = {} + then = {}, ) } else if ( !controller.isLaunching && @@ -446,7 +468,7 @@ class TransitionAnimator( ViewRootSync.synchronizeNextDraw( openingWindowSyncView, transitionContainer, - then = {} + then = {}, ) } @@ -464,7 +486,7 @@ class TransitionAnimator( container, fadeWindowBackgroundLayer, drawHole, - controller.isLaunching + controller.isLaunching, ) controller.onTransitionAnimationProgress(state, progress, linearProgress) } @@ -488,7 +510,7 @@ class TransitionAnimator( transitionContainer: View, fadeWindowBackgroundLayer: Boolean, drawHole: Boolean, - isLaunching: Boolean + isLaunching: Boolean, ) { // Update position. transitionContainer.getLocationOnScreen(transitionContainerLocation) @@ -496,7 +518,7 @@ class TransitionAnimator( state.left - transitionContainerLocation[0], state.top - transitionContainerLocation[1], state.right - transitionContainerLocation[0], - state.bottom - transitionContainerLocation[1] + state.bottom - transitionContainerLocation[1], ) // Update radius. @@ -517,7 +539,7 @@ class TransitionAnimator( timings, linearProgress, timings.contentBeforeFadeOutDelay, - timings.contentBeforeFadeOutDuration + timings.contentBeforeFadeOutDuration, ) if (isLaunching) { @@ -531,7 +553,7 @@ class TransitionAnimator( timings, linearProgress, timings.contentAfterFadeInDelay, - timings.contentAfterFadeInDuration + timings.contentAfterFadeInDuration, ) val alpha = 1 - @@ -561,7 +583,7 @@ class TransitionAnimator( timings, linearProgress, timings.contentAfterFadeInDelay, - timings.contentAfterFadeInDuration + timings.contentAfterFadeInDuration, ) val alpha = 1 - |