Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb6c71b9 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Android (Google) Code Review
Browse files

Merge changes I49c6095f,Id14bee4b into tm-qpr-dev

* changes:
  Support Activity launches above the expandable
  Format Kotlin code in SysUI Animation lib using ktfmt
parents e8bbc028 7bb86722
Loading
Loading
Loading
Loading
+182 −122
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ class ActivityLaunchAnimator(
    companion object {
        /** The timings when animating a View into an app. */
        @JvmField
        val TIMINGS = LaunchAnimator.Timings(
        val TIMINGS =
            LaunchAnimator.Timings(
                totalDuration = 500L,
                contentBeforeFadeOutDelay = 0L,
                contentBeforeFadeOutDuration = 150L,
@@ -72,13 +73,12 @@ class ActivityLaunchAnimator(
         * showing the app (which is under the dialog window) so that the dialog window dim is fully
         * faded out, to avoid flicker.
         */
        val DIALOG_TIMINGS = TIMINGS.copy(
            contentBeforeFadeOutDuration = 200L,
            contentAfterFadeInDelay = 200L
        )
        val DIALOG_TIMINGS =
            TIMINGS.copy(contentBeforeFadeOutDuration = 200L, contentAfterFadeInDelay = 200L)

        /** The interpolators when animating a View or a dialog into an app. */
        val INTERPOLATORS = LaunchAnimator.Interpolators(
        val INTERPOLATORS =
            LaunchAnimator.Interpolators(
                positionInterpolator = Interpolators.EMPHASIZED,
                positionXInterpolator = createPositionXInterpolator(),
                contentBeforeFadeOutInterpolator = Interpolators.LINEAR_OUT_SLOW_IN,
@@ -98,7 +98,8 @@ class ActivityLaunchAnimator(
        private const val LAUNCH_TIMEOUT = 1000L

        private fun createPositionXInterpolator(): Interpolator {
            val path = Path().apply {
            val path =
                Path().apply {
                    moveTo(0f, 0f)
                    cubicTo(0.1217f, 0.0462f, 0.15f, 0.4686f, 0.1667f, 0.66f)
                    cubicTo(0.1834f, 0.8878f, 0.1667f, 1f, 1f, 1f)
@@ -150,14 +151,18 @@ class ActivityLaunchAnimator(
            return
        }

        val callback = this.callback ?: throw IllegalStateException(
            "ActivityLaunchAnimator.callback must be set before using this animator")
        val callback =
            this.callback
                ?: throw IllegalStateException(
                    "ActivityLaunchAnimator.callback must be set before using this animator"
                )
        val runner = Runner(controller)
        val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen

        // Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the
        // keyguard with the animation
        val animationAdapter = if (!hideKeyguardWithAnimation) {
        val animationAdapter =
            if (!hideKeyguardWithAnimation) {
                RemoteAnimationAdapter(
                    runner,
                    TIMINGS.totalDuration,
@@ -171,8 +176,12 @@ class ActivityLaunchAnimator(
        // activity launches.
        if (packageName != null && animationAdapter != null) {
            try {
                ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart(
                    packageName, animationAdapter, null /* launchCookie */)
                ActivityTaskManager.getService()
                    .registerRemoteAnimationForNextActivityStart(
                        packageName,
                        animationAdapter,
                        null /* launchCookie */
                    )
            } catch (e: RemoteException) {
                Log.w(TAG, "Unable to register the remote animation", e)
            }
@@ -188,8 +197,11 @@ class ActivityLaunchAnimator(
                (launchResult == ActivityManager.START_DELIVERED_TO_TOP &&
                    hideKeyguardWithAnimation)

        Log.i(TAG, "launchResult=$launchResult willAnimate=$willAnimate " +
                "hideKeyguardWithAnimation=$hideKeyguardWithAnimation")
        Log.i(
            TAG,
            "launchResult=$launchResult willAnimate=$willAnimate " +
                "hideKeyguardWithAnimation=$hideKeyguardWithAnimation"
        )
        controller.callOnIntentStartedOnMainThread(willAnimate)

        // If we expect an animation, post a timeout to cancel it in case the remote animation is
@@ -206,9 +218,7 @@ class ActivityLaunchAnimator(

    private fun Controller.callOnIntentStartedOnMainThread(willAnimate: Boolean) {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            this.launchContainer.context.mainExecutor.execute {
                this.onIntentStarted(willAnimate)
            }
            this.launchContainer.context.mainExecutor.execute { this.onIntentStarted(willAnimate) }
        } else {
            this.onIntentStarted(willAnimate)
        }
@@ -246,8 +256,7 @@ class ActivityLaunchAnimator(
    }

    /** Create a new animation [Runner] controlled by [controller]. */
    @VisibleForTesting
    fun createRunner(controller: Controller): Runner = Runner(controller)
    @VisibleForTesting fun createRunner(controller: Controller): Runner = Runner(controller)

    interface PendingIntentStarter {
        /**
@@ -271,19 +280,16 @@ class ActivityLaunchAnimator(

    interface Listener {
        /** Called when an activity launch animation started. */
        @JvmDefault
        fun onLaunchAnimationStart() {}
        @JvmDefault fun onLaunchAnimationStart() {}

        /**
         * Called when an activity launch animation is finished. This will be called if and only if
         * [onLaunchAnimationStart] was called earlier.
         */
        @JvmDefault
        fun onLaunchAnimationEnd() {}
        @JvmDefault fun onLaunchAnimationEnd() {}

        /** Called when an activity launch animation made progress. */
        @JvmDefault
        fun onLaunchAnimationProgress(linearProgress: Float) {}
        @JvmDefault fun onLaunchAnimationProgress(linearProgress: Float) {}
    }

    /**
@@ -326,6 +332,17 @@ class ActivityLaunchAnimator(
        val isDialogLaunch: Boolean
            get() = false

        /**
         * Whether the expandable controller by this [Controller] is below the launching window that
         * is going to be animated.
         *
         * This should be `false` when launching an app from the shade or status bar, given that
         * they are drawn above all apps. This is usually `true` when using this launcher in a
         * normal app or a launcher, that are drawn below the animating activity/window.
         */
        val isBelowAnimatingWindow: Boolean
            get() = false

        /**
         * The intent was started. If [willAnimate] is false, nothing else will happen and the
         * animation will not be started.
@@ -394,9 +411,7 @@ class ActivityLaunchAnimator(
                return
            }

            context.mainExecutor.execute {
                startAnimation(apps, nonApps, iCallback)
            }
            context.mainExecutor.execute { startAnimation(apps, nonApps, iCallback) }
        }

        private fun startAnimation(
@@ -408,9 +423,7 @@ class ActivityLaunchAnimator(
                Log.d(TAG, "Remote animation started")
            }

            val window = apps?.firstOrNull {
                it.mode == RemoteAnimationTarget.MODE_OPENING
            }
            val window = apps?.firstOrNull { it.mode == RemoteAnimationTarget.MODE_OPENING }

            if (window == null) {
                Log.i(TAG, "Aborting the animation as no window is opening")
@@ -420,23 +433,26 @@ class ActivityLaunchAnimator(
                return
            }

            val navigationBar = nonApps?.firstOrNull {
            val navigationBar =
                nonApps?.firstOrNull {
                    it.windowType == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
                }

            val windowBounds = window.screenSpaceBounds
            val endState = LaunchAnimator.State(
            val endState =
                LaunchAnimator.State(
                    top = windowBounds.top,
                    bottom = windowBounds.bottom,
                    left = windowBounds.left,
                    right = windowBounds.right
                )
            val callback = this@ActivityLaunchAnimator.callback!!
            val windowBackgroundColor = window.taskInfo?.let { callback.getBackgroundColor(it) }
                    ?: window.backgroundColor
            val windowBackgroundColor =
                window.taskInfo?.let { callback.getBackgroundColor(it) } ?: window.backgroundColor

            // Make sure we use the modified timings when animating a dialog into an app.
            val launchAnimator = if (controller.isDialogLaunch) {
            val launchAnimator =
                if (controller.isDialogLaunch) {
                    dialogToAppAnimator
                } else {
                    launchAnimator
@@ -446,12 +462,14 @@ class ActivityLaunchAnimator(
            // instead of recomputing isExpandingFullyAbove here.
            val isExpandingFullyAbove =
                launchAnimator.isExpandingFullyAbove(controller.launchContainer, endState)
            val endRadius = if (isExpandingFullyAbove) {
            val endRadius =
                if (isExpandingFullyAbove) {
                    // Most of the time, expanding fully above the root view means expanding in full
                    // screen.
                    ScreenDecorationsUtils.getWindowCornerRadius(context)
                } else {
                // This usually means we are in split screen mode, so 2 out of 4 corners will have
                    // This usually means we are in split screen mode, so 2 out of 4 corners will
                    // have
                    // a radius of 0.
                    0f
                }
@@ -460,7 +478,8 @@ class ActivityLaunchAnimator(

            // We animate the opening window and delegate the view expansion to [this.controller].
            val delegate = this.controller
            val controller = object : LaunchAnimator.Controller by delegate {
            val controller =
                object : Controller by delegate {
                    override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
                        listeners.forEach { it.onLaunchAnimationStart() }
                        delegate.onLaunchAnimationStart(isExpandingFullyAbove)
@@ -477,10 +496,10 @@ class ActivityLaunchAnimator(
                        progress: Float,
                        linearProgress: Float
                    ) {
                    // Apply the state to the window only if it is visible, i.e. when the expanding
                    // view is *not* visible.
                        // Apply the state to the window only if it is visible, i.e. when the
                        // expanding view is *not* visible.
                        if (!state.visible) {
                        applyStateToWindow(window, state)
                            applyStateToWindow(window, state, linearProgress)
                        }
                        navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }

@@ -489,11 +508,21 @@ class ActivityLaunchAnimator(
                    }
                }

            animation = launchAnimator.startAnimation(
                controller, endState, windowBackgroundColor, drawHole = true)
            animation =
                launchAnimator.startAnimation(
                    controller,
                    endState,
                    windowBackgroundColor,
                    fadeOutWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
                    drawHole = !controller.isBelowAnimatingWindow,
                )
        }

        private fun applyStateToWindow(window: RemoteAnimationTarget, state: LaunchAnimator.State) {
        private fun applyStateToWindow(
            window: RemoteAnimationTarget,
            state: LaunchAnimator.State,
            linearProgress: Float,
        ) {
            if (transactionApplierView.viewRootImpl == null) {
                // If the view root we synchronize with was detached, don't apply any transaction
                // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
@@ -535,14 +564,33 @@ class ActivityLaunchAnimator(
                windowCropF.bottom.roundToInt()
            )

            // The alpha of the opening window. If it opens above the expandable, then it should
            // fade in progressively. Otherwise, it should be fully opaque and will be progressively
            // revealed as the window background color layer above the window fades out.
            val alpha =
                if (controller.isBelowAnimatingWindow) {
                    val windowProgress =
                        LaunchAnimator.getProgress(
                            TIMINGS,
                            linearProgress,
                            TIMINGS.contentAfterFadeInDelay,
                            TIMINGS.contentAfterFadeInDuration
                        )

                    INTERPOLATORS.contentAfterFadeInInterpolator.getInterpolation(windowProgress)
                } else {
                    1f
                }

            // The scale will also be applied to the corner radius, so we divide by the scale to
            // keep the original radius. We use the max of (topCornerRadius, bottomCornerRadius) to
            // make sure that the window does not draw itself behind the expanding view. This is
            // especially important for lock screen animations, where the window is not clipped by
            // the shade.
            val cornerRadius = maxOf(state.topCornerRadius, state.bottomCornerRadius) / scale
            val params = SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(window.leash)
                .withAlpha(1f)
            val params =
                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(window.leash)
                    .withAlpha(alpha)
                    .withMatrix(matrix)
                    .withWindowCrop(windowCrop)
                    .withCornerRadius(cornerRadius)
@@ -563,14 +611,21 @@ class ActivityLaunchAnimator(
                return
            }

            val fadeInProgress = LaunchAnimator.getProgress(TIMINGS, linearProgress,
                ANIMATION_DELAY_NAV_FADE_IN, ANIMATION_DURATION_NAV_FADE_OUT)
            val fadeInProgress =
                LaunchAnimator.getProgress(
                    TIMINGS,
                    linearProgress,
                    ANIMATION_DELAY_NAV_FADE_IN,
                    ANIMATION_DURATION_NAV_FADE_OUT
                )

            val params = SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(navigationBar.leash)
            if (fadeInProgress > 0) {
                matrix.reset()
                matrix.setTranslate(
                    0f, (state.top - navigationBar.sourceContainerBounds.top).toFloat())
                    0f,
                    (state.top - navigationBar.sourceContainerBounds.top).toFloat()
                )
                windowCrop.set(state.left, 0, state.right, state.height)
                params
                    .withAlpha(NAV_FADE_IN_INTERPOLATOR.getInterpolation(fadeInProgress))
@@ -578,8 +633,13 @@ class ActivityLaunchAnimator(
                    .withWindowCrop(windowCrop)
                    .withVisibility(true)
            } else {
                val fadeOutProgress = LaunchAnimator.getProgress(TIMINGS, linearProgress, 0,
                    ANIMATION_DURATION_NAV_FADE_OUT)
                val fadeOutProgress =
                    LaunchAnimator.getProgress(
                        TIMINGS,
                        linearProgress,
                        0,
                        ANIMATION_DURATION_NAV_FADE_OUT
                    )
                params.withAlpha(1f - NAV_FADE_OUT_INTERPOLATOR.getInterpolation(fadeOutProgress))
            }

Loading