Loading packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/TopLevelWindowEffectsTest.kt +29 −48 Original line number Diff line number Diff line Loading @@ -115,8 +115,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { @Test fun testNoProgressWhenSqueezeEffectDisabled() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isEffectEnabled.value = false underTest.start() Loading @@ -127,8 +126,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fun testSqueezeEffectStarts_afterInitialDelay() = kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay Loading @@ -146,8 +144,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -164,8 +161,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fun testSqueezeEffectNotStarted_whenUpEventReceivedBefore100Millis() = kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay Loading @@ -174,8 +170,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { // subtract 1ms time to simulate initial delay duration is yet not finished advanceTime((expectedDelay - 1).milliseconds) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() animatorTestRule.advanceTimeBy(1) Loading @@ -189,8 +184,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -199,8 +193,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { advanceTime((expectedDelay + 1).milliseconds) animatorTestRule.advanceTimeBy(1) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() animatorTestRule.advanceTimeBy(1) } Loading @@ -211,8 +204,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { val expectedDelay = DEFAULT_INITIAL_DELAY_MILLIS + 750 - DEFAULT_LONG_PRESS_POWER_DURATION_MILLIS fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -222,8 +214,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { animatorTestRule.advanceTimeBy(1) val timesCancelledBefore = vibratorHelper.timesCancelled fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() animatorTestRule.advanceTimeBy(1) Loading @@ -240,8 +231,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { val expectedDelay = DEFAULT_INITIAL_DELAY_MILLIS + 750 - DEFAULT_LONG_PRESS_POWER_DURATION_MILLIS fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -250,8 +240,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { advanceTime((expectedDelay - 1).milliseconds) animatorTestRule.advanceTimeBy(1) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() Loading @@ -266,8 +255,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { DEFAULT_INITIAL_DELAY_MILLIS + 750 - DEFAULT_LONG_PRESS_POWER_DURATION_MILLIS fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false setInvocationEffectEnabled(false) underTest.start() Loading @@ -287,8 +275,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() // Advance time past initial delay to start the animation Loading @@ -303,8 +290,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { runCurrent() // Process collection of isPowerButtonLongPressed // Release power button fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() // Triggers cancelSqueeze, but it should not interrupt // On long-press the LPP haptic effect plays cancelling any previous haptic effect Loading Loading @@ -337,8 +323,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() advanceTime((initialDelay + 1).milliseconds) Loading @@ -363,8 +348,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { assertThat(vibratorHelper.timesCancelled).isEqualTo(timesCancelledBefore) // Release power button (should not change anything as animation is finished) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() } Loading @@ -376,8 +360,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() // Advance past initial delay advanceTime((initialDelay + 1).milliseconds) Loading @@ -399,8 +382,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { assertThat(vibratorHelper.hasVibratedWithEffects(zoomOutHaptics.vibration)).isTrue() // Release power button (does not affect completed animation) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() } Loading @@ -412,8 +394,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() // Advance time past initial delay to start the animation Loading @@ -428,8 +409,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { assertThat(progressBeforeCancel).isLessThan(1f) // Release power button before long press is detected fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() // Process button release, triggers cancelSqueeze // cancelSqueeze calls hapticPlayer.cancel() Loading @@ -447,8 +427,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { // Setup: Enable effect and trigger power button down val initialDelay = 50L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay // Action: Start the effect and advance time past initial delay to start animation Loading @@ -465,8 +444,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { // Setup: Enable effect and trigger power button down val initialDelay = 50L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay // Action: Start the effect Loading Loading @@ -494,8 +472,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { // Setup: Enable effect and trigger power button down val initialDelay = 50L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay // Action: Start the effect Loading @@ -511,8 +488,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { reset(kosmos.mockTopUiController, kosmos.notificationShadeWindowController) // Action: Release power button to cancel the animation fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() // Allow cancellation animation to complete animatorTestRule.advanceTimeBy(DEFAULT_OUTWARD_EFFECT_DURATION_MS) Loading @@ -532,4 +508,9 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { .setRequestTopUi(isRequested, TopLevelWindowEffects.TAG) } } private fun Kosmos.setInvocationEffectEnabled(enabled: Boolean) { fakeSqueezeEffectRepository.isEffectEnabled.value = enabled fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = enabled } } packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/data/repository/SqueezeEffectRepositoryTest.kt +17 −12 Original line number Diff line number Diff line Loading @@ -93,10 +93,9 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(false) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(isEffectEnabled).isFalse() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading @@ -105,12 +104,14 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(true) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) val isPowerButtonPressedAsSingleGesture by collectLastValue(underTest.isPowerButtonPressedAsSingleGesture) // no events sent from KeyGestureEvent to imitate it was disabled from PWM assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(isEffectEnabled).isTrue() assertThat(isPowerButtonPressedAsSingleGesture).isFalse() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading @@ -119,8 +120,9 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(false) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) val isPowerButtonPressedAsSingleGesture by collectLastValue(underTest.isPowerButtonPressedAsSingleGesture) verify(inputManager) .registerKeyGestureEventListener( Loading @@ -134,7 +136,8 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { .build() keyGestureEventListenerCaptor.value.onKeyGestureEvent(event) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(isEffectEnabled).isFalse() assertThat(isPowerButtonPressedAsSingleGesture).isTrue() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading @@ -143,8 +146,9 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(true) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) val isPowerButtonPressedAsSingleGesture by collectLastValue(underTest.isPowerButtonPressedAsSingleGesture) verify(inputManager) .registerKeyGestureEventListener( Loading @@ -158,7 +162,8 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { .build() keyGestureEventListenerCaptor.value.onKeyGestureEvent(event) assertThat(isEffectEnabledAndPowerButtonPressed).isTrue() assertThat(isEffectEnabled).isTrue() assertThat(isPowerButtonPressedAsSingleGesture).isTrue() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/domain/interactor/SqueezeEffectInteractorTest.kt +60 −24 Original line number Diff line number Diff line Loading @@ -42,50 +42,86 @@ class SqueezeEffectInteractorTest : SysuiTestCase() { } @Test fun testIsSqueezeEffectDisabled_whenDisabledInRepository() = fun powerButtonSemantics_powerKeyNotDownAsSingleGestureAndDisabled_cancelsSqueeze() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(powerButtonSemantics).isEqualTo(PowerButtonSemantics.CANCEL_SQUEEZE) } @Test fun testShowInvocationEffect_whenEnabledInRepository() = fun powerButtonSemantics_powerKeyNotDownAsSingleGestureAndEnabled_cancelsSqueeze() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.isEffectEnabled.value = true fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isTrue() assertThat(powerButtonSemantics).isEqualTo(PowerButtonSemantics.CANCEL_SQUEEZE) } @Test fun testPowerKeyInKeyCombination_powerKeyNotDownAsSingleGesture() = fun powerButtonSemantics_powerKeyDownAsSingleGestureAndDisabled_isNull() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(powerButtonSemantics).isNull() } @Test fun testPowerKeyNotInKeyCombination_powerKeyDownAsSingleGesture() = fun powerButtonSemantics_powerKeyDownAsSingleGestureAndEnabled_withRumble_startsEffect() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.isEffectEnabled.value = true fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.shouldUseHapticRumble = true val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isTrue() assertThat(powerButtonSemantics) .isEqualTo(PowerButtonSemantics.START_SQUEEZE_WITH_RUMBLE) } @Test fun powerButtonSemantics_powerKeyDownAsSingleGestureAndEnabled_withoutRumble_startsEffect() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabled.value = true fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.shouldUseHapticRumble = false val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(powerButtonSemantics) .isEqualTo(PowerButtonSemantics.START_SQUEEZE_WITHOUT_RUMBLE) } @Test fun powerButtonSemantics_onLPPAndDisabledAndPowerKeyAsSingleGesture_playsAssistantHaptics() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.isPowerButtonLongPressed.value = true val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(powerButtonSemantics) .isEqualTo(PowerButtonSemantics.PLAY_DEFAULT_ASSISTANT_HAPTICS) } @Test fun powerButtonSemantics_onLPPAndDisabledAndPowerKeyNotAsSingleGesture_cancelsSqueeze() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonLongPressed.value = true val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(powerButtonSemantics).isEqualTo(PowerButtonSemantics.CANCEL_SQUEEZE) } } packages/SystemUI/src/com/android/systemui/topwindoweffects/TopLevelWindowEffects.kt +13 −14 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.systemui.topwindoweffects import android.os.Handler import android.os.SystemProperties import android.view.Choreographer import androidx.annotation.VisibleForTesting import androidx.core.animation.Animator Loading @@ -32,6 +31,7 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.topui.TopUiController import com.android.systemui.topui.TopUiControllerRefactor import com.android.systemui.topwindoweffects.domain.interactor.PowerButtonSemantics import com.android.systemui.topwindoweffects.domain.interactor.SqueezeEffectInteractor import com.android.systemui.topwindoweffects.ui.viewmodel.SqueezeEffectHapticPlayer import com.android.wm.shell.appzoomout.AppZoomOut Loading Loading @@ -80,18 +80,15 @@ constructor( override fun start() { applicationScope.launch { squeezeEffectInteractor.isEffectEnabledAndPowerButtonPressedAsSingleGesture .collectLatest { enabledAndPressed -> if (enabledAndPressed) { val hapticsOption = SystemProperties.get( /*key=*/ "persist.lpp_invocation.haptics", /*def=*/ "no_rumble", ) val useHapticRumble = hapticsOption == "with_rumble" startSqueeze(useHapticRumble) } else { cancelSqueeze() squeezeEffectInteractor.powerButtonSemantics.collectLatest { semantics -> when (semantics) { PowerButtonSemantics.START_SQUEEZE_WITH_RUMBLE -> startSqueeze(useHapticRumble = true) PowerButtonSemantics.START_SQUEEZE_WITHOUT_RUMBLE -> startSqueeze(useHapticRumble = false) PowerButtonSemantics.CANCEL_SQUEEZE -> cancelSqueeze() PowerButtonSemantics.PLAY_DEFAULT_ASSISTANT_HAPTICS -> playDefaultAssistantHaptic() } } } Loading Loading @@ -187,6 +184,8 @@ constructor( } } private fun playDefaultAssistantHaptic() = hapticPlayer?.playDefaultAssistantEffect() override fun dump(pw: PrintWriter, args: Array<out String>) { pw.println("$TAG:") pw.println(" isAnimationInterruptible=$isAnimationInterruptible") Loading packages/SystemUI/src/com/android/systemui/topwindoweffects/data/repository/SqueezeEffectRepository.kt +5 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ interface SqueezeEffectRepository { val isSqueezeEffectHapticEnabled: Boolean val isEffectEnabledAndPowerButtonPressedAsSingleGesture: Flow<Boolean> val isEffectEnabled: Flow<Boolean> val isPowerButtonPressedAsSingleGesture: Flow<Boolean> val isPowerButtonLongPressed: Flow<Boolean> Loading @@ -33,5 +35,7 @@ interface SqueezeEffectRepository { fun getInvocationEffectOutAnimationDurationMillis(): Long fun useHapticRumble(): Boolean fun dump(pw: PrintWriter, args: Array<out String>) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/TopLevelWindowEffectsTest.kt +29 −48 Original line number Diff line number Diff line Loading @@ -115,8 +115,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { @Test fun testNoProgressWhenSqueezeEffectDisabled() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isEffectEnabled.value = false underTest.start() Loading @@ -127,8 +126,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fun testSqueezeEffectStarts_afterInitialDelay() = kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay Loading @@ -146,8 +144,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -164,8 +161,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fun testSqueezeEffectNotStarted_whenUpEventReceivedBefore100Millis() = kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay Loading @@ -174,8 +170,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { // subtract 1ms time to simulate initial delay duration is yet not finished advanceTime((expectedDelay - 1).milliseconds) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() animatorTestRule.advanceTimeBy(1) Loading @@ -189,8 +184,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { val expectedDelay = 100L fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -199,8 +193,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { advanceTime((expectedDelay + 1).milliseconds) animatorTestRule.advanceTimeBy(1) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() animatorTestRule.advanceTimeBy(1) } Loading @@ -211,8 +204,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { val expectedDelay = DEFAULT_INITIAL_DELAY_MILLIS + 750 - DEFAULT_LONG_PRESS_POWER_DURATION_MILLIS fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -222,8 +214,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { animatorTestRule.advanceTimeBy(1) val timesCancelledBefore = vibratorHelper.timesCancelled fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() animatorTestRule.advanceTimeBy(1) Loading @@ -240,8 +231,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { val expectedDelay = DEFAULT_INITIAL_DELAY_MILLIS + 750 - DEFAULT_LONG_PRESS_POWER_DURATION_MILLIS fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay underTest.start() Loading @@ -250,8 +240,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { advanceTime((expectedDelay - 1).milliseconds) animatorTestRule.advanceTimeBy(1) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() Loading @@ -266,8 +255,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { DEFAULT_INITIAL_DELAY_MILLIS + 750 - DEFAULT_LONG_PRESS_POWER_DURATION_MILLIS fakeSqueezeEffectRepository.isSqueezeEffectHapticEnabled = true fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = expectedDelay fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false setInvocationEffectEnabled(false) underTest.start() Loading @@ -287,8 +275,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() // Advance time past initial delay to start the animation Loading @@ -303,8 +290,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { runCurrent() // Process collection of isPowerButtonLongPressed // Release power button fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() // Triggers cancelSqueeze, but it should not interrupt // On long-press the LPP haptic effect plays cancelling any previous haptic effect Loading Loading @@ -337,8 +323,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() advanceTime((initialDelay + 1).milliseconds) Loading @@ -363,8 +348,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { assertThat(vibratorHelper.timesCancelled).isEqualTo(timesCancelledBefore) // Release power button (should not change anything as animation is finished) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() } Loading @@ -376,8 +360,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() // Advance past initial delay advanceTime((initialDelay + 1).milliseconds) Loading @@ -399,8 +382,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { assertThat(vibratorHelper.hasVibratedWithEffects(zoomOutHaptics.vibration)).isTrue() // Release power button (does not affect completed animation) fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() } Loading @@ -412,8 +394,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay underTest.start() fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) runCurrent() // Advance time past initial delay to start the animation Loading @@ -428,8 +409,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { assertThat(progressBeforeCancel).isLessThan(1f) // Release power button before long press is detected fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() // Process button release, triggers cancelSqueeze // cancelSqueeze calls hapticPlayer.cancel() Loading @@ -447,8 +427,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { // Setup: Enable effect and trigger power button down val initialDelay = 50L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay // Action: Start the effect and advance time past initial delay to start animation Loading @@ -465,8 +444,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { // Setup: Enable effect and trigger power button down val initialDelay = 50L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay // Action: Start the effect Loading Loading @@ -494,8 +472,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { kosmos.runTest { // Setup: Enable effect and trigger power button down val initialDelay = 50L fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true setInvocationEffectEnabled(true) fakeSqueezeEffectRepository.invocationEffectInitialDelayMs = initialDelay // Action: Start the effect Loading @@ -511,8 +488,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { reset(kosmos.mockTopUiController, kosmos.notificationShadeWindowController) // Action: Release power button to cancel the animation fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false runCurrent() // Allow cancellation animation to complete animatorTestRule.advanceTimeBy(DEFAULT_OUTWARD_EFFECT_DURATION_MS) Loading @@ -532,4 +508,9 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { .setRequestTopUi(isRequested, TopLevelWindowEffects.TAG) } } private fun Kosmos.setInvocationEffectEnabled(enabled: Boolean) { fakeSqueezeEffectRepository.isEffectEnabled.value = enabled fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = enabled } }
packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/data/repository/SqueezeEffectRepositoryTest.kt +17 −12 Original line number Diff line number Diff line Loading @@ -93,10 +93,9 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(false) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(isEffectEnabled).isFalse() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading @@ -105,12 +104,14 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(true) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) val isPowerButtonPressedAsSingleGesture by collectLastValue(underTest.isPowerButtonPressedAsSingleGesture) // no events sent from KeyGestureEvent to imitate it was disabled from PWM assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(isEffectEnabled).isTrue() assertThat(isPowerButtonPressedAsSingleGesture).isFalse() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading @@ -119,8 +120,9 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(false) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) val isPowerButtonPressedAsSingleGesture by collectLastValue(underTest.isPowerButtonPressedAsSingleGesture) verify(inputManager) .registerKeyGestureEventListener( Loading @@ -134,7 +136,8 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { .build() keyGestureEventListenerCaptor.value.onKeyGestureEvent(event) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(isEffectEnabled).isFalse() assertThat(isPowerButtonPressedAsSingleGesture).isTrue() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading @@ -143,8 +146,9 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { kosmos.runTest { fakeInvocationEffectPreferences.setInvocationEffectEnabledByAssistant(true) val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val isEffectEnabled by collectLastValue(underTest.isEffectEnabled) val isPowerButtonPressedAsSingleGesture by collectLastValue(underTest.isPowerButtonPressedAsSingleGesture) verify(inputManager) .registerKeyGestureEventListener( Loading @@ -158,7 +162,8 @@ class SqueezeEffectRepositoryTest : SysuiTestCase() { .build() keyGestureEventListenerCaptor.value.onKeyGestureEvent(event) assertThat(isEffectEnabledAndPowerButtonPressed).isTrue() assertThat(isEffectEnabled).isTrue() assertThat(isPowerButtonPressedAsSingleGesture).isTrue() } @EnableFlags(Flags.FLAG_ENABLE_LPP_ASSIST_INVOCATION_EFFECT) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/domain/interactor/SqueezeEffectInteractorTest.kt +60 −24 Original line number Diff line number Diff line Loading @@ -42,50 +42,86 @@ class SqueezeEffectInteractorTest : SysuiTestCase() { } @Test fun testIsSqueezeEffectDisabled_whenDisabledInRepository() = fun powerButtonSemantics_powerKeyNotDownAsSingleGestureAndDisabled_cancelsSqueeze() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(powerButtonSemantics).isEqualTo(PowerButtonSemantics.CANCEL_SQUEEZE) } @Test fun testShowInvocationEffect_whenEnabledInRepository() = fun powerButtonSemantics_powerKeyNotDownAsSingleGestureAndEnabled_cancelsSqueeze() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.isEffectEnabled.value = true fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isTrue() assertThat(powerButtonSemantics).isEqualTo(PowerButtonSemantics.CANCEL_SQUEEZE) } @Test fun testPowerKeyInKeyCombination_powerKeyNotDownAsSingleGesture() = fun powerButtonSemantics_powerKeyDownAsSingleGestureAndDisabled_isNull() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isFalse() assertThat(powerButtonSemantics).isNull() } @Test fun testPowerKeyNotInKeyCombination_powerKeyDownAsSingleGesture() = fun powerButtonSemantics_powerKeyDownAsSingleGestureAndEnabled_withRumble_startsEffect() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabledAndPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.isEffectEnabled.value = true fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.shouldUseHapticRumble = true val isEffectEnabledAndPowerButtonPressed by collectLastValue(underTest.isEffectEnabledAndPowerButtonPressedAsSingleGesture) val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(isEffectEnabledAndPowerButtonPressed).isTrue() assertThat(powerButtonSemantics) .isEqualTo(PowerButtonSemantics.START_SQUEEZE_WITH_RUMBLE) } @Test fun powerButtonSemantics_powerKeyDownAsSingleGestureAndEnabled_withoutRumble_startsEffect() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabled.value = true fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.shouldUseHapticRumble = false val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(powerButtonSemantics) .isEqualTo(PowerButtonSemantics.START_SQUEEZE_WITHOUT_RUMBLE) } @Test fun powerButtonSemantics_onLPPAndDisabledAndPowerKeyAsSingleGesture_playsAssistantHaptics() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = true fakeSqueezeEffectRepository.isPowerButtonLongPressed.value = true val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(powerButtonSemantics) .isEqualTo(PowerButtonSemantics.PLAY_DEFAULT_ASSISTANT_HAPTICS) } @Test fun powerButtonSemantics_onLPPAndDisabledAndPowerKeyNotAsSingleGesture_cancelsSqueeze() = kosmos.runTest { fakeSqueezeEffectRepository.isEffectEnabled.value = false fakeSqueezeEffectRepository.isPowerButtonPressedAsSingleGesture.value = false fakeSqueezeEffectRepository.isPowerButtonLongPressed.value = true val powerButtonSemantics by collectLastValue(underTest.powerButtonSemantics) assertThat(powerButtonSemantics).isEqualTo(PowerButtonSemantics.CANCEL_SQUEEZE) } }
packages/SystemUI/src/com/android/systemui/topwindoweffects/TopLevelWindowEffects.kt +13 −14 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.systemui.topwindoweffects import android.os.Handler import android.os.SystemProperties import android.view.Choreographer import androidx.annotation.VisibleForTesting import androidx.core.animation.Animator Loading @@ -32,6 +31,7 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.topui.TopUiController import com.android.systemui.topui.TopUiControllerRefactor import com.android.systemui.topwindoweffects.domain.interactor.PowerButtonSemantics import com.android.systemui.topwindoweffects.domain.interactor.SqueezeEffectInteractor import com.android.systemui.topwindoweffects.ui.viewmodel.SqueezeEffectHapticPlayer import com.android.wm.shell.appzoomout.AppZoomOut Loading Loading @@ -80,18 +80,15 @@ constructor( override fun start() { applicationScope.launch { squeezeEffectInteractor.isEffectEnabledAndPowerButtonPressedAsSingleGesture .collectLatest { enabledAndPressed -> if (enabledAndPressed) { val hapticsOption = SystemProperties.get( /*key=*/ "persist.lpp_invocation.haptics", /*def=*/ "no_rumble", ) val useHapticRumble = hapticsOption == "with_rumble" startSqueeze(useHapticRumble) } else { cancelSqueeze() squeezeEffectInteractor.powerButtonSemantics.collectLatest { semantics -> when (semantics) { PowerButtonSemantics.START_SQUEEZE_WITH_RUMBLE -> startSqueeze(useHapticRumble = true) PowerButtonSemantics.START_SQUEEZE_WITHOUT_RUMBLE -> startSqueeze(useHapticRumble = false) PowerButtonSemantics.CANCEL_SQUEEZE -> cancelSqueeze() PowerButtonSemantics.PLAY_DEFAULT_ASSISTANT_HAPTICS -> playDefaultAssistantHaptic() } } } Loading Loading @@ -187,6 +184,8 @@ constructor( } } private fun playDefaultAssistantHaptic() = hapticPlayer?.playDefaultAssistantEffect() override fun dump(pw: PrintWriter, args: Array<out String>) { pw.println("$TAG:") pw.println(" isAnimationInterruptible=$isAnimationInterruptible") Loading
packages/SystemUI/src/com/android/systemui/topwindoweffects/data/repository/SqueezeEffectRepository.kt +5 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ interface SqueezeEffectRepository { val isSqueezeEffectHapticEnabled: Boolean val isEffectEnabledAndPowerButtonPressedAsSingleGesture: Flow<Boolean> val isEffectEnabled: Flow<Boolean> val isPowerButtonPressedAsSingleGesture: Flow<Boolean> val isPowerButtonLongPressed: Flow<Boolean> Loading @@ -33,5 +35,7 @@ interface SqueezeEffectRepository { fun getInvocationEffectOutAnimationDurationMillis(): Long fun useHapticRumble(): Boolean fun dump(pw: PrintWriter, args: Array<out String>) }