Loading packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.keyguard.KeyguardUnfoldTransition 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 Loading Loading @@ -95,4 +96,6 @@ interface SysUIUnfoldComponent { fun getUnfoldHapticsPlayer(): UnfoldHapticsPlayer fun getUnfoldLightRevealOverlayAnimation(): UnfoldLightRevealOverlayAnimation fun getUnfoldKeyguardVisibilityManager(): UnfoldKeyguardVisibilityManager } packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt 0 → 100644 +39 −0 Original line number Diff line number Diff line 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" packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt +50 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListen 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 Loading Loading @@ -56,6 +57,9 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { @Mock private lateinit var rotationChangeProvider: RotationChangeProvider @Mock private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider @Captor private lateinit var rotationListener: ArgumentCaptor<RotationListener> Loading Loading @@ -87,6 +91,7 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { screenOnStatusProvider, foldProvider, activityTypeProvider, unfoldKeyguardVisibilityProvider, rotationChangeProvider, context.mainExecutor, handler Loading Loading @@ -379,6 +384,47 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING) } @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) Loading Loading @@ -445,6 +491,10 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { 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) { Loading packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt +17 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ import com.android.systemui.unfold.updates.hinge.HingeAngleProvider 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 Loading Loading @@ -57,7 +60,8 @@ class UnfoldSharedModule { scaleAwareProviderFactory.wrap(baseProgressProvider).apply { // Always present callback that logs animation beginning and end. addCallback(tracingListener) }) } ) } @Provides Loading @@ -77,4 +81,16 @@ class UnfoldSharedModule { } else { EmptyHingeAngleProvider } @Provides @Singleton fun unfoldKeyguardVisibilityProvider( impl: UnfoldKeyguardVisibilityManagerImpl ): UnfoldKeyguardVisibilityProvider = impl @Provides @Singleton fun unfoldKeyguardVisibilityManager( impl: UnfoldKeyguardVisibilityManagerImpl ): UnfoldKeyguardVisibilityManager = impl } packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt +6 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES 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 Loading @@ -42,6 +43,7 @@ constructor( 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 Loading Loading @@ -152,12 +154,13 @@ constructor( */ 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 Loading Loading @@ -257,7 +260,7 @@ fun @receiver:FoldUpdate Int.name() = } 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 Loading Loading
packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.keyguard.KeyguardUnfoldTransition 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 Loading Loading @@ -95,4 +96,6 @@ interface SysUIUnfoldComponent { fun getUnfoldHapticsPlayer(): UnfoldHapticsPlayer fun getUnfoldLightRevealOverlayAnimation(): UnfoldLightRevealOverlayAnimation fun getUnfoldKeyguardVisibilityManager(): UnfoldKeyguardVisibilityManager }
packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt 0 → 100644 +39 −0 Original line number Diff line number Diff line 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"
packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt +50 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListen 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 Loading Loading @@ -56,6 +57,9 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { @Mock private lateinit var rotationChangeProvider: RotationChangeProvider @Mock private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider @Captor private lateinit var rotationListener: ArgumentCaptor<RotationListener> Loading Loading @@ -87,6 +91,7 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { screenOnStatusProvider, foldProvider, activityTypeProvider, unfoldKeyguardVisibilityProvider, rotationChangeProvider, context.mainExecutor, handler Loading Loading @@ -379,6 +384,47 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING) } @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) Loading Loading @@ -445,6 +491,10 @@ class DeviceFoldStateProviderTest : SysuiTestCase() { 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) { Loading
packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt +17 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ import com.android.systemui.unfold.updates.hinge.HingeAngleProvider 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 Loading Loading @@ -57,7 +60,8 @@ class UnfoldSharedModule { scaleAwareProviderFactory.wrap(baseProgressProvider).apply { // Always present callback that logs animation beginning and end. addCallback(tracingListener) }) } ) } @Provides Loading @@ -77,4 +81,16 @@ class UnfoldSharedModule { } else { EmptyHingeAngleProvider } @Provides @Singleton fun unfoldKeyguardVisibilityProvider( impl: UnfoldKeyguardVisibilityManagerImpl ): UnfoldKeyguardVisibilityProvider = impl @Provides @Singleton fun unfoldKeyguardVisibilityManager( impl: UnfoldKeyguardVisibilityManagerImpl ): UnfoldKeyguardVisibilityManager = impl }
packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt +6 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES 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 Loading @@ -42,6 +43,7 @@ constructor( 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 Loading Loading @@ -152,12 +154,13 @@ constructor( */ 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 Loading Loading @@ -257,7 +260,7 @@ fun @receiver:FoldUpdate Int.name() = } 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 Loading