Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +14 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.view.View import android.view.View.OnLayoutChangeListener import android.view.ViewGroup import android.view.ViewGroup.OnHierarchyChangeListener import android.view.WindowInsets import android.view.WindowInsets.Type import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.internal.jank.InteractionJankMonitor Loading Loading @@ -242,11 +244,18 @@ object KeyguardRootViewBinder { } ) view.setOnApplyWindowInsetsListener { v: View, insets: WindowInsets -> val insetTypes = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout() viewModel.topInset = insets.getInsetsIgnoringVisibility(insetTypes).top insets } return object : DisposableHandle { override fun dispose() { disposableHandle.dispose() view.removeOnLayoutChangeListener(onLayoutChangeListener) view.setOnHierarchyChangeListener(null) view.setOnApplyWindowInsetsListener(null) childViews.clear() } } Loading Loading @@ -288,7 +297,6 @@ object KeyguardRootViewBinder { oldBottom: Int ) { val nsslPlaceholder = v.findViewById(R.id.nssl_placeholder) as View? if (nsslPlaceholder != null) { // After layout, ensure the notifications are positioned correctly viewModel.onSharedNotificationContainerPositionChanged( Loading @@ -296,6 +304,11 @@ object KeyguardRootViewBinder { nsslPlaceholder.bottom.toFloat(), ) } val ksv = v.findViewById(R.id.keyguard_status_view) as View? if (ksv != null) { viewModel.statusViewTop = ksv.top } } } Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +10 −2 Original line number Diff line number Diff line Loading @@ -65,7 +65,12 @@ constructor( */ private val previewMode = MutableStateFlow(PreviewMode()) public var clockControllerProvider: Provider<ClockController>? = null var clockControllerProvider: Provider<ClockController>? = null /** System insets that keyguard needs to stay out of */ var topInset: Int = 0 /** Status view top, without translation added in */ var statusViewTop: Int = 0 val burnInLayerVisibility: Flow<Int> = keyguardTransitionInteractor.startedKeyguardState Loading Loading @@ -102,9 +107,12 @@ constructor( scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation), ) } else { // Ensure the desired translation doesn't encroach on the top inset val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt() val translationY = -(statusViewTop - Math.max(topInset, statusViewTop + burnInY)) BurnInModel( translationX = MathUtils.lerp(0, burnIn.translationX, interpolation).toInt(), translationY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt(), translationY = translationY, scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation), scaleClockOnly = true, ) Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +33 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,8 @@ class KeyguardRootViewModelTest : SysuiTestCase() { val translationY by collectLastValue(underTest.translationY) val scale by collectLastValue(underTest.scale) underTest.statusViewTop = 100 // Set to dozing (on AOD) dozeAmountTransitionStep.emit(TransitionStep(value = 1f)) // Trigger a change to the burn-in model Loading @@ -199,6 +201,37 @@ class KeyguardRootViewModelTest : SysuiTestCase() { assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */)) } @Test fun translationAndScaleFromBurnFullyDozingStaysOutOfTopInset() = testScope.runTest { val translationX by collectLastValue(underTest.translationX) val translationY by collectLastValue(underTest.translationY) val scale by collectLastValue(underTest.scale) underTest.statusViewTop = 100 underTest.topInset = 80 // Set to dozing (on AOD) dozeAmountTransitionStep.emit(TransitionStep(value = 1f)) // Trigger a change to the burn-in model burnInFlow.value = BurnInModel( translationX = 20, translationY = -30, scale = 0.5f, ) assertThat(translationX).isEqualTo(20) // -20 instead of -30, due to inset of 80 assertThat(translationY).isEqualTo(-20) assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */)) // Set to the beginning of GONE->AOD transition goneToAodTransitionStep.emit(TransitionStep(value = 0f)) assertThat(translationX).isEqualTo(0) assertThat(translationY).isEqualTo(0) assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */)) } @Test fun translationAndScaleFromBurnInUseScaleOnly() = testScope.runTest { Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +14 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.view.View import android.view.View.OnLayoutChangeListener import android.view.ViewGroup import android.view.ViewGroup.OnHierarchyChangeListener import android.view.WindowInsets import android.view.WindowInsets.Type import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.internal.jank.InteractionJankMonitor Loading Loading @@ -242,11 +244,18 @@ object KeyguardRootViewBinder { } ) view.setOnApplyWindowInsetsListener { v: View, insets: WindowInsets -> val insetTypes = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout() viewModel.topInset = insets.getInsetsIgnoringVisibility(insetTypes).top insets } return object : DisposableHandle { override fun dispose() { disposableHandle.dispose() view.removeOnLayoutChangeListener(onLayoutChangeListener) view.setOnHierarchyChangeListener(null) view.setOnApplyWindowInsetsListener(null) childViews.clear() } } Loading Loading @@ -288,7 +297,6 @@ object KeyguardRootViewBinder { oldBottom: Int ) { val nsslPlaceholder = v.findViewById(R.id.nssl_placeholder) as View? if (nsslPlaceholder != null) { // After layout, ensure the notifications are positioned correctly viewModel.onSharedNotificationContainerPositionChanged( Loading @@ -296,6 +304,11 @@ object KeyguardRootViewBinder { nsslPlaceholder.bottom.toFloat(), ) } val ksv = v.findViewById(R.id.keyguard_status_view) as View? if (ksv != null) { viewModel.statusViewTop = ksv.top } } } Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +10 −2 Original line number Diff line number Diff line Loading @@ -65,7 +65,12 @@ constructor( */ private val previewMode = MutableStateFlow(PreviewMode()) public var clockControllerProvider: Provider<ClockController>? = null var clockControllerProvider: Provider<ClockController>? = null /** System insets that keyguard needs to stay out of */ var topInset: Int = 0 /** Status view top, without translation added in */ var statusViewTop: Int = 0 val burnInLayerVisibility: Flow<Int> = keyguardTransitionInteractor.startedKeyguardState Loading Loading @@ -102,9 +107,12 @@ constructor( scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation), ) } else { // Ensure the desired translation doesn't encroach on the top inset val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt() val translationY = -(statusViewTop - Math.max(topInset, statusViewTop + burnInY)) BurnInModel( translationX = MathUtils.lerp(0, burnIn.translationX, interpolation).toInt(), translationY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt(), translationY = translationY, scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation), scaleClockOnly = true, ) Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +33 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,8 @@ class KeyguardRootViewModelTest : SysuiTestCase() { val translationY by collectLastValue(underTest.translationY) val scale by collectLastValue(underTest.scale) underTest.statusViewTop = 100 // Set to dozing (on AOD) dozeAmountTransitionStep.emit(TransitionStep(value = 1f)) // Trigger a change to the burn-in model Loading @@ -199,6 +201,37 @@ class KeyguardRootViewModelTest : SysuiTestCase() { assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */)) } @Test fun translationAndScaleFromBurnFullyDozingStaysOutOfTopInset() = testScope.runTest { val translationX by collectLastValue(underTest.translationX) val translationY by collectLastValue(underTest.translationY) val scale by collectLastValue(underTest.scale) underTest.statusViewTop = 100 underTest.topInset = 80 // Set to dozing (on AOD) dozeAmountTransitionStep.emit(TransitionStep(value = 1f)) // Trigger a change to the burn-in model burnInFlow.value = BurnInModel( translationX = 20, translationY = -30, scale = 0.5f, ) assertThat(translationX).isEqualTo(20) // -20 instead of -30, due to inset of 80 assertThat(translationY).isEqualTo(-20) assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */)) // Set to the beginning of GONE->AOD transition goneToAodTransitionStep.emit(TransitionStep(value = 0f)) assertThat(translationX).isEqualTo(0) assertThat(translationY).isEqualTo(0) assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */)) } @Test fun translationAndScaleFromBurnInUseScaleOnly() = testScope.runTest { Loading