Merge "Trigger unfold animation without treshold while on keyguard" into tm-qpr-dev
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
index 209d93f..1482cfc 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
@@ -20,6 +20,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shade.NotificationPanelUnfoldAnimationController
import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.util.kotlin.getOrNull
@@ -95,4 +96,6 @@
fun getUnfoldHapticsPlayer(): UnfoldHapticsPlayer
fun getUnfoldLightRevealOverlayAnimation(): UnfoldLightRevealOverlayAnimation
+
+ fun getUnfoldKeyguardVisibilityManager(): UnfoldKeyguardVisibilityManager
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt
new file mode 100644
index 0000000..59558ac
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt
@@ -0,0 +1,39 @@
+package com.android.systemui.unfold
+
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
+import com.android.systemui.util.kotlin.getOrNull
+import java.util.Optional
+import javax.inject.Inject
+
+/**
+ * Used to set the keyguard visibility state to [UnfoldKeyguardVisibilityManager].
+ *
+ * It is not possible to directly inject a sysui class (e.g. [KeyguardStateController]) into
+ * [DeviceStateProvider], as it can't depend on google sysui directly. So,
+ * [UnfoldKeyguardVisibilityManager] is provided to clients, that can set the keyguard visibility
+ * accordingly.
+ */
+@SysUISingleton
+class UnfoldKeyguardVisibilityListener
+@Inject
+constructor(
+ keyguardStateController: KeyguardStateController,
+ unfoldComponent: Optional<SysUIUnfoldComponent>,
+) {
+
+ private val unfoldKeyguardVisibilityManager =
+ unfoldComponent.getOrNull()?.getUnfoldKeyguardVisibilityManager()
+
+ private val delegate = { keyguardStateController.isVisible }
+
+ fun init() {
+ unfoldKeyguardVisibilityManager?.setKeyguardVisibleDelegate(delegate).also {
+ Log.d(TAG, "setKeyguardVisibleDelegate set")
+ }
+ }
+}
+
+private const val TAG = "UnfoldKeyguardVisibilityListener"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 7d5f06c..6086e16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.google.common.truth.Truth.assertThat
@@ -56,6 +57,9 @@
@Mock
private lateinit var rotationChangeProvider: RotationChangeProvider
+ @Mock
+ private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider
+
@Captor
private lateinit var rotationListener: ArgumentCaptor<RotationListener>
@@ -87,6 +91,7 @@
screenOnStatusProvider,
foldProvider,
activityTypeProvider,
+ unfoldKeyguardVisibilityProvider,
rotationChangeProvider,
context.mainExecutor,
handler
@@ -380,6 +385,47 @@
}
@Test
+ fun startClosingEvent_whileNotOnKeyguardAndNotOnLauncher_doesNotTriggerBeforeThreshold() {
+ setKeyguardVisibility(visible = false)
+ setupForegroundActivityType(isHomeActivity = false)
+ sendHingeAngleEvent(180)
+
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+ assertThat(foldUpdates).isEmpty()
+ }
+
+ @Test
+ fun startClosingEvent_whileKeyguardStateNotAvailable_triggerBeforeThreshold() {
+ setKeyguardVisibility(visible = null)
+ sendHingeAngleEvent(180)
+
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
+ fun startClosingEvent_whileonKeyguard_doesTriggerBeforeThreshold() {
+ setKeyguardVisibility(visible = true)
+ sendHingeAngleEvent(180)
+
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
+ fun startClosingEvent_whileNotOnKeyguard_triggersAfterThreshold() {
+ setKeyguardVisibility(visible = false)
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
+
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
fun screenOff_whileFolded_hingeAngleProviderRemainsOff() {
setFoldState(folded = true)
assertThat(testHingeAngleProvider.isStarted).isFalse()
@@ -445,6 +491,10 @@
whenever(activityTypeProvider.isHomeActivity).thenReturn(isHomeActivity)
}
+ private fun setKeyguardVisibility(visible: Boolean?) {
+ whenever(unfoldKeyguardVisibilityProvider.isKeyguardVisible).thenReturn(visible)
+ }
+
private fun simulateTimeout(waitTime: Long = HALF_OPENED_TIMEOUT_MILLIS) {
val runnableDelay = scheduledRunnableDelay ?: throw Exception("No runnable scheduled.")
if (waitTime >= runnableDelay) {
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 8f4ee4d..3fa5469 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -28,6 +28,9 @@
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManagerImpl
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import dagger.Module
import dagger.Provides
import java.util.Optional
@@ -57,7 +60,8 @@
scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
// Always present callback that logs animation beginning and end.
addCallback(tracingListener)
- })
+ }
+ )
}
@Provides
@@ -77,4 +81,16 @@
} else {
EmptyHingeAngleProvider
}
+
+ @Provides
+ @Singleton
+ fun unfoldKeyguardVisibilityProvider(
+ impl: UnfoldKeyguardVisibilityManagerImpl
+ ): UnfoldKeyguardVisibilityProvider = impl
+
+ @Provides
+ @Singleton
+ fun unfoldKeyguardVisibilityManager(
+ impl: UnfoldKeyguardVisibilityManagerImpl
+ ): UnfoldKeyguardVisibilityManager = impl
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 808128d..5b45897 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -31,6 +31,7 @@
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.util.CurrentActivityTypeProvider
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -42,6 +43,7 @@
private val screenStatusProvider: ScreenStatusProvider,
private val foldProvider: FoldProvider,
private val activityTypeProvider: CurrentActivityTypeProvider,
+ private val unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider,
private val rotationChangeProvider: RotationChangeProvider,
@UnfoldMain private val mainExecutor: Executor,
@UnfoldMain private val handler: Handler
@@ -152,12 +154,13 @@
*/
private fun getClosingThreshold(): Int? {
val isHomeActivity = activityTypeProvider.isHomeActivity ?: return null
+ val isKeyguardVisible = unfoldKeyguardVisibilityProvider.isKeyguardVisible == true
if (DEBUG) {
- Log.d(TAG, "isHomeActivity=$isHomeActivity")
+ Log.d(TAG, "isHomeActivity=$isHomeActivity, isOnKeyguard=$isKeyguardVisible")
}
- return if (isHomeActivity) {
+ return if (isHomeActivity || isKeyguardVisible) {
null
} else {
START_CLOSING_ON_APPS_THRESHOLD_DEGREES
@@ -257,7 +260,7 @@
}
private const val TAG = "DeviceFoldProvider"
-private const val DEBUG = false
+private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
/** Threshold after which we consider the device fully unfolded. */
@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/UnfoldKeyguardVisibilityProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/UnfoldKeyguardVisibilityProvider.kt
new file mode 100644
index 0000000..9f0efa0
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/UnfoldKeyguardVisibilityProvider.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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.unfold.util
+
+import java.lang.ref.WeakReference
+import javax.inject.Inject
+import javax.inject.Singleton
+
+interface UnfoldKeyguardVisibilityProvider {
+ /**
+ * True when the keyguard is visible.
+ *
+ * Might be [null] when it is not known.
+ */
+ val isKeyguardVisible: Boolean?
+}
+
+/** Used to notify keyguard visibility. */
+interface UnfoldKeyguardVisibilityManager {
+ /** Sets the delegate. [delegate] should return true when the keyguard is visible. */
+ fun setKeyguardVisibleDelegate(delegate: () -> Boolean)
+}
+
+/**
+ * Keeps a [WeakReference] for the keyguard visibility provider.
+ *
+ * It is a weak reference because this is in the global scope, while the delegate might be set from
+ * another subcomponent (that might have shorter lifespan).
+ */
+@Singleton
+class UnfoldKeyguardVisibilityManagerImpl @Inject constructor() :
+ UnfoldKeyguardVisibilityProvider, UnfoldKeyguardVisibilityManager {
+
+ private var delegatedProvider: WeakReference<() -> Boolean?>? = null
+
+ override fun setKeyguardVisibleDelegate(delegate: () -> Boolean) {
+ delegatedProvider = WeakReference(delegate)
+ }
+
+ override val isKeyguardVisible: Boolean?
+ get() = delegatedProvider?.get()?.invoke()
+}