Merge "Unfold transition - Apply based on state" into tm-qpr-dev
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
index f974e27..edd150c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
@@ -19,6 +19,8 @@
import android.content.Context
import android.view.ViewGroup
import com.android.systemui.R
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction.END
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction.START
@@ -36,27 +38,29 @@
@Inject
constructor(
private val context: Context,
- unfoldProgressProvider: NaturalRotationUnfoldProgressProvider
+ statusBarStateController: StatusBarStateController,
+ unfoldProgressProvider: NaturalRotationUnfoldProgressProvider,
) {
/** Certain views only need to move if they are not currently centered */
var statusViewCentered = false
- private val filterSplitShadeOnly = { !statusViewCentered }
- private val filterNever = { true }
+ private val filterKeyguardAndSplitShadeOnly: () -> Boolean = {
+ statusBarStateController.getState() == KEYGUARD && !statusViewCentered }
+ private val filterKeyguard: () -> Boolean = { statusBarStateController.getState() == KEYGUARD }
private val translateAnimator by lazy {
UnfoldConstantTranslateAnimator(
viewsIdToTranslate =
setOf(
- ViewIdToTranslate(R.id.keyguard_status_area, START, filterNever),
+ ViewIdToTranslate(R.id.keyguard_status_area, START, filterKeyguard),
ViewIdToTranslate(
- R.id.lockscreen_clock_view_large, START, filterSplitShadeOnly),
- ViewIdToTranslate(R.id.lockscreen_clock_view, START, filterNever),
+ R.id.lockscreen_clock_view_large, START, filterKeyguardAndSplitShadeOnly),
+ ViewIdToTranslate(R.id.lockscreen_clock_view, START, filterKeyguard),
ViewIdToTranslate(
- R.id.notification_stack_scroller, END, filterSplitShadeOnly),
- ViewIdToTranslate(R.id.start_button, START, filterNever),
- ViewIdToTranslate(R.id.end_button, END, filterNever)),
+ R.id.notification_stack_scroller, END, filterKeyguardAndSplitShadeOnly),
+ ViewIdToTranslate(R.id.start_button, START, filterKeyguard),
+ ViewIdToTranslate(R.id.end_button, END, filterKeyguard)),
progressProvider = unfoldProgressProvider)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
index ba779c6..639172f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
@@ -19,6 +19,9 @@
import android.content.Context
import android.view.ViewGroup
import com.android.systemui.R
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState.SHADE
+import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction.END
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction.START
@@ -30,17 +33,24 @@
@SysUIUnfoldScope
class NotificationPanelUnfoldAnimationController
@Inject
-constructor(private val context: Context, progressProvider: NaturalRotationUnfoldProgressProvider) {
+constructor(
+ private val context: Context,
+ statusBarStateController: StatusBarStateController,
+ progressProvider: NaturalRotationUnfoldProgressProvider,
+) {
+
+ private val filterShade: () -> Boolean = { statusBarStateController.getState() == SHADE ||
+ statusBarStateController.getState() == SHADE_LOCKED }
private val translateAnimator by lazy {
UnfoldConstantTranslateAnimator(
viewsIdToTranslate =
setOf(
- ViewIdToTranslate(R.id.quick_settings_panel, START),
- ViewIdToTranslate(R.id.notification_stack_scroller, END),
- ViewIdToTranslate(R.id.rightLayout, END),
- ViewIdToTranslate(R.id.clock, START),
- ViewIdToTranslate(R.id.date, START)),
+ ViewIdToTranslate(R.id.quick_settings_panel, START, filterShade),
+ ViewIdToTranslate(R.id.notification_stack_scroller, END, filterShade),
+ ViewIdToTranslate(R.id.rightLayout, END, filterShade),
+ ViewIdToTranslate(R.id.clock, START, filterShade),
+ ViewIdToTranslate(R.id.date, START, filterShade)),
progressProvider = progressProvider)
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
index 6c1f008..bb03f28 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
@@ -22,9 +22,13 @@
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState.KEYGUARD
+import com.android.systemui.statusbar.StatusBarState.SHADE
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -33,7 +37,6 @@
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
/**
@@ -50,7 +53,9 @@
@Mock private lateinit var parent: ViewGroup
- private lateinit var keyguardUnfoldTransition: KeyguardUnfoldTransition
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
+
+ private lateinit var underTest: KeyguardUnfoldTransition
private lateinit var progressListener: TransitionProgressListener
private var xTranslationMax = 0f
@@ -61,10 +66,10 @@
xTranslationMax =
context.resources.getDimensionPixelSize(R.dimen.keyguard_unfold_translation_x).toFloat()
- keyguardUnfoldTransition = KeyguardUnfoldTransition(context, progressProvider)
+ underTest = KeyguardUnfoldTransition(context, statusBarStateController, progressProvider)
- keyguardUnfoldTransition.setup(parent)
- keyguardUnfoldTransition.statusViewCentered = false
+ underTest.setup(parent)
+ underTest.statusViewCentered = false
verify(progressProvider).addCallback(capture(progressListenerCaptor))
progressListener = progressListenerCaptor.value
@@ -72,10 +77,11 @@
@Test
fun onTransition_centeredViewDoesNotMove() {
- keyguardUnfoldTransition.statusViewCentered = true
+ whenever(statusBarStateController.getState()).thenReturn(KEYGUARD)
+ underTest.statusViewCentered = true
val view = View(context)
- `when`(parent.findViewById<View>(R.id.lockscreen_clock_view_large)).thenReturn(view)
+ whenever(parent.findViewById<View>(R.id.lockscreen_clock_view_large)).thenReturn(view)
progressListener.onTransitionStarted()
assertThat(view.translationX).isZero()
@@ -89,4 +95,44 @@
progressListener.onTransitionFinished()
assertThat(view.translationX).isZero()
}
+
+ @Test
+ fun whenInShadeState_viewDoesNotMove() {
+ whenever(statusBarStateController.getState()).thenReturn(SHADE)
+
+ val view = View(context)
+ whenever(parent.findViewById<View>(R.id.lockscreen_clock_view_large)).thenReturn(view)
+
+ progressListener.onTransitionStarted()
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0f)
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0.5f)
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionFinished()
+ assertThat(view.translationX).isZero()
+ }
+
+ @Test
+ fun whenInKeyguardState_viewDoesMove() {
+ whenever(statusBarStateController.getState()).thenReturn(KEYGUARD)
+
+ val view = View(context)
+ whenever(parent.findViewById<View>(R.id.lockscreen_clock_view_large)).thenReturn(view)
+
+ progressListener.onTransitionStarted()
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0f)
+ assertThat(view.translationX).isEqualTo(xTranslationMax)
+
+ progressListener.onTransitionProgress(0.5f)
+ assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
+
+ progressListener.onTransitionFinished()
+ assertThat(view.translationX).isZero()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
new file mode 100644
index 0000000..db6fc13
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import android.testing.AndroidTestingRunner
+import android.view.View
+import android.view.ViewGroup
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState.KEYGUARD
+import com.android.systemui.statusbar.StatusBarState.SHADE
+import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+/**
+ * Translates items away/towards the hinge when the device is opened/closed. This is controlled by
+ * the set of ids, which also dictact which direction to move and when, via a filter fn.
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
+
+ @Mock private lateinit var progressProvider: NaturalRotationUnfoldProgressProvider
+
+ @Captor private lateinit var progressListenerCaptor: ArgumentCaptor<TransitionProgressListener>
+
+ @Mock private lateinit var parent: ViewGroup
+
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
+
+ private lateinit var underTest: NotificationPanelUnfoldAnimationController
+ private lateinit var progressListener: TransitionProgressListener
+ private var xTranslationMax = 0f
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+
+ xTranslationMax =
+ context.resources.getDimensionPixelSize(R.dimen.notification_side_paddings).toFloat()
+
+ underTest =
+ NotificationPanelUnfoldAnimationController(
+ context,
+ statusBarStateController,
+ progressProvider
+ )
+ underTest.setup(parent)
+
+ verify(progressProvider).addCallback(capture(progressListenerCaptor))
+ progressListener = progressListenerCaptor.value
+ }
+
+ @Test
+ fun whenInKeyguardState_viewDoesNotMove() {
+ whenever(statusBarStateController.getState()).thenReturn(KEYGUARD)
+
+ val view = View(context)
+ whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
+
+ progressListener.onTransitionStarted()
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0f)
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0.5f)
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionFinished()
+ assertThat(view.translationX).isZero()
+ }
+
+ @Test
+ fun whenInShadeState_viewDoesMove() {
+ whenever(statusBarStateController.getState()).thenReturn(SHADE)
+
+ val view = View(context)
+ whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
+
+ progressListener.onTransitionStarted()
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0f)
+ assertThat(view.translationX).isEqualTo(xTranslationMax)
+
+ progressListener.onTransitionProgress(0.5f)
+ assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
+
+ progressListener.onTransitionFinished()
+ assertThat(view.translationX).isZero()
+ }
+
+ @Test
+ fun whenInShadeLockedState_viewDoesMove() {
+ whenever(statusBarStateController.getState()).thenReturn(SHADE_LOCKED)
+
+ val view = View(context)
+ whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
+
+ progressListener.onTransitionStarted()
+ assertThat(view.translationX).isZero()
+
+ progressListener.onTransitionProgress(0f)
+ assertThat(view.translationX).isEqualTo(xTranslationMax)
+
+ progressListener.onTransitionProgress(0.5f)
+ assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
+
+ progressListener.onTransitionFinished()
+ assertThat(view.translationX).isZero()
+ }
+}