diff options
| author | 2024-01-03 23:00:58 +0000 | |
|---|---|---|
| committer | 2024-01-08 20:45:49 +0000 | |
| commit | 4865cbfaa32d912a6d49c6df014d8f7996f0172a (patch) | |
| tree | c1a3932e0caa98f74087825d275d85e81e44ee68 | |
| parent | 182ae92f1e2ee8e109b7d9247d6dde9a42781149 (diff) | |
Migrate stepping animation to blueprint for default clock
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint
DEVELOPMENT
Bug: 315167622
Test: manually test stepping animation with flag on and off
Change-Id: Ieb697646fb3a4ada3c2cdac505f941dfea5e04db
5 files changed, 109 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 2a54a4eee657..d372f5a616b1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt index 05fe0b25381d..bf763b4e1f99 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt @@ -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,7 +78,13 @@ object KeyguardClockViewBinder { launch { if (!migrateClocksToBlueprint()) return@launch viewModel.clockShouldBeCentered.collect { - applyConstraints(clockSection, keyguardRootView, true) + viewModel.clock?.let { + if (it.largeClock.config.hasCustomPositionUpdatedAnimation) { + playClockCenteringAnimation(clockSection, keyguardRootView, it) + } else { + applyConstraints(clockSection, keyguardRootView, true) + } + } } } } @@ -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) + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt index 92270ad31664..81ce8f04d302 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt index f2b28d964314..f33aed03856c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt @@ -29,4 +29,8 @@ class KeyguardRootView( ConstraintLayout( context, attrs, - ) + ) { + init { + clipChildren = false + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index a5c1cf1af191..654ed392ac1b 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -1751,14 +1751,9 @@ 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)); - } + mKeyguardStatusViewController.updateAlignment( + layout, mSplitShadeEnabled, shouldBeCentered, animate); + mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered)); } private boolean shouldKeyguardStatusViewBeCentered() { |