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

Commit a14da088 authored by Sherry Zhou's avatar Sherry Zhou Committed by Android (Google) Code Review
Browse files

Merge "Migrate stepping animation to blueprint for default clock" into main

parents 853ac103 4865cbfa
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;

import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION;
import static com.android.systemui.Flags.migrateClocksToBlueprint;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;

import android.animation.Animator;
@@ -492,7 +493,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
            boolean splitShadeEnabled,
            boolean shouldBeCentered,
            boolean animate) {
        mKeyguardClockSwitchController.setSplitShadeCentered(splitShadeEnabled && shouldBeCentered);
        if (migrateClocksToBlueprint()) {
            mKeyguardInteractor.setClockShouldBeCentered(mSplitShadeEnabled && shouldBeCentered);
        } else {
            mKeyguardClockSwitchController.setSplitShadeCentered(
                    splitShadeEnabled && shouldBeCentered);
        }
        if (mStatusViewCentered == shouldBeCentered) {
            return;
        }
@@ -548,8 +554,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
        ClockController clock = mKeyguardClockSwitchController.getClock();
        boolean customClockAnimation = clock != null
                && clock.getLargeClock().getConfig().getHasCustomPositionUpdatedAnimation();

        if (customClockAnimation) {
        // When migrateClocksToBlueprint is on, customized clock animation is conducted in
        // KeyguardClockViewBinder
        if (customClockAnimation && !migrateClocksToBlueprint()) {
            // Find the clock, so we can exclude it from this transition.
            FrameLayout clockContainerView = mView.findViewById(R.id.lockscreen_clock_view_large);

+89 −2
Original line number Diff line number Diff line
@@ -16,13 +16,20 @@

package com.android.systemui.keyguard.ui.binder

import android.animation.Animator
import android.animation.ValueAnimator
import android.transition.Transition
import android.transition.TransitionManager
import android.transition.TransitionSet
import android.transition.TransitionValues
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.constraintlayout.helper.widget.Layer
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
import com.android.systemui.Flags.migrateClocksToBlueprint
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection
@@ -32,6 +39,8 @@ import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.res.R
import kotlinx.coroutines.launch

private const val KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION_MS = 1000L

object KeyguardClockViewBinder {
    @JvmStatic
    fun bind(
@@ -69,12 +78,18 @@ object KeyguardClockViewBinder {
                launch {
                    if (!migrateClocksToBlueprint()) return@launch
                    viewModel.clockShouldBeCentered.collect {
                        viewModel.clock?.let {
                            if (it.largeClock.config.hasCustomPositionUpdatedAnimation) {
                                playClockCenteringAnimation(clockSection, keyguardRootView, it)
                            } else {
                                applyConstraints(clockSection, keyguardRootView, true)
                            }
                        }
                    }
                }
            }
        }
    }

    private fun cleanupClockViews(
        clockController: ClockController?,
@@ -125,12 +140,84 @@ object KeyguardClockViewBinder {
        clockSection: ClockSection,
        rootView: ConstraintLayout,
        animated: Boolean,
        set: TransitionSet? = null,
    ) {
        val constraintSet = ConstraintSet().apply { clone(rootView) }
        clockSection.applyConstraints(constraintSet)
        if (animated) {
            TransitionManager.beginDelayedTransition(rootView)
            set?.let { TransitionManager.beginDelayedTransition(rootView, it) }
                ?: run { TransitionManager.beginDelayedTransition(rootView) }
        }
        constraintSet.applyTo(rootView)
    }

    private fun playClockCenteringAnimation(
        clockSection: ClockSection,
        keyguardRootView: ConstraintLayout,
        clock: ClockController,
    ) {
        // Find the clock, so we can exclude it from this transition.
        val clockView = clock.largeClock.view
        val set = TransitionSet()
        val adapter = SplitShadeTransitionAdapter(clock)
        adapter.setInterpolator(Interpolators.LINEAR)
        adapter.setDuration(KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION_MS)
        adapter.addTarget(clockView)
        set.addTransition(adapter)
        applyConstraints(clockSection, keyguardRootView, true, set)
    }

    internal class SplitShadeTransitionAdapter
    @VisibleForTesting
    constructor(private val clock: ClockController) : Transition() {
        private fun captureValues(transitionValues: TransitionValues) {
            transitionValues.values[PROP_BOUNDS_LEFT] = transitionValues.view.left
            val locationInWindowTmp = IntArray(2)
            transitionValues.view.getLocationInWindow(locationInWindowTmp)
            transitionValues.values[PROP_X_IN_WINDOW] = locationInWindowTmp[0]
        }

        override fun captureEndValues(transitionValues: TransitionValues) {
            captureValues(transitionValues)
        }

        override fun captureStartValues(transitionValues: TransitionValues) {
            captureValues(transitionValues)
        }

        override fun createAnimator(
            sceneRoot: ViewGroup,
            startValues: TransitionValues?,
            endValues: TransitionValues?
        ): Animator? {
            if (startValues == null || endValues == null) {
                return null
            }
            val anim = ValueAnimator.ofFloat(0f, 1f)
            val fromLeft = startValues.values[PROP_BOUNDS_LEFT] as Int
            val fromWindowX = startValues.values[PROP_X_IN_WINDOW] as Int
            val toWindowX = endValues.values[PROP_X_IN_WINDOW] as Int
            // Using windowX, to determine direction, instead of left, as in RTL the difference of
            // toLeft - fromLeft is always positive, even when moving left.
            val direction = if (toWindowX - fromWindowX > 0) 1 else -1
            anim.addUpdateListener { animation: ValueAnimator ->
                clock.largeClock.animations.onPositionUpdated(
                    fromLeft,
                    direction,
                    animation.animatedFraction
                )
            }
            return anim
        }

        override fun getTransitionProperties(): Array<String> {
            return TRANSITION_PROPERTIES
        }

        companion object {
            private const val PROP_BOUNDS_LEFT = "splitShadeTransitionAdapter:boundsLeft"
            private const val PROP_X_IN_WINDOW = "splitShadeTransitionAdapter:xInWindow"
            private val TRANSITION_PROPERTIES = arrayOf(PROP_BOUNDS_LEFT, PROP_X_IN_WINDOW)
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.Flags.migrateClocksToBlueprint
import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
@@ -42,6 +43,7 @@ object KeyguardSmartspaceViewBinder {
        keyguardRootView.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                launch {
                    if (!migrateClocksToBlueprint()) return@launch
                    clockViewModel.hasCustomWeatherDataDisplay.collect { hasCustomWeatherDataDisplay
                        ->
                        if (hasCustomWeatherDataDisplay) {
+5 −1
Original line number Diff line number Diff line
@@ -29,4 +29,8 @@ class KeyguardRootView(
    ConstraintLayout(
        context,
        attrs,
    )
    ) {
    init {
        clipChildren = false
    }
}
+3 −8
Original line number Diff line number Diff line
@@ -1751,15 +1751,10 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
        } else {
            layout = mNotificationContainerParent;
        }

        if (migrateClocksToBlueprint()) {
            mKeyguardInteractor.setClockShouldBeCentered(mSplitShadeEnabled && shouldBeCentered);
        } else {
        mKeyguardStatusViewController.updateAlignment(
                layout, mSplitShadeEnabled, shouldBeCentered, animate);
        mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered));
    }
    }

    private boolean shouldKeyguardStatusViewBeCentered() {
        if (mSplitShadeEnabled) {