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()
+    }
+}