Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt +27 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,13 @@ constructor( @Main private val mainExecutor: Executor, ) { private var action: Action? = null private var panelState: Int = -1 @MainThread fun enable(onPanelInteraction: Runnable) { if (action == null) { action = Action(onPanelInteraction) shadeExpansionStateManager.addStateListener(this::onPanelStateChanged) shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged) } else { Log.e(TAG, "Already enabled") Loading @@ -32,6 +34,8 @@ constructor( if (action != null) { Log.i(TAG, "Disable dectector") action = null panelState = -1 shadeExpansionStateManager.removeStateListener(this::onPanelStateChanged) shadeExpansionStateManager.removeExpansionListener(this::onPanelExpansionChanged) } } Loading @@ -40,13 +44,34 @@ constructor( private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) = mainExecutor.execute { action?.let { if (event.tracking || (event.expanded && event.fraction > 0)) { Log.i(TAG, "Detected panel interaction, event: $event") if (event.tracking || (event.expanded && event.fraction > 0 && panelState == 1)) { Log.i(TAG, "onPanelExpansionChanged, event: $event") it.onPanelInteraction.run() disable() } } } @AnyThread private fun onPanelStateChanged(state: Int) = mainExecutor.execute { // When device owner set screen lock type as Swipe, and install work profile with // pin/pattern/password & fingerprint or face, if work profile allow user to verify // by BP, it is possible that BP will be displayed when keyguard is closing, in this // case event.expanded = true and event.fraction > 0, so BP will be closed, adding // panel state into consideration is workaround^2, this workaround works because // onPanelStateChanged is earlier than onPanelExpansionChanged // we don't want to close BP in below case // // | Action | tracking | expanded | fraction | panelState | // | HeadsUp | NA | NA | NA | 1 | // | b/285111529 | false | true | > 0 | 2 | // Note: HeadsUp behavior was changed, so we can't got onPanelExpansionChanged now panelState = state Log.i(TAG, "onPanelStateChanged, state: $state") } } private data class Action(val onPanelInteraction: Runnable) Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt +13 −3 Original line number Diff line number Diff line Loading @@ -20,12 +20,12 @@ import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.shade.ShadeExpansionStateManager import org.junit.Assert import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions import org.mockito.junit.MockitoJUnit Loading Loading @@ -63,10 +63,10 @@ class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() { } @Test fun testEnableDetector_expandOnly_shouldPostRunnable() { fun testEnableDetector_expandOnly_shouldNotPostRunnable() { detector.enable(action) shadeExpansionStateManager.onPanelExpansionChanged(1.0f, true, false, 0f) verify(action).run() verifyZeroInteractions(action) } @Test Loading @@ -84,4 +84,14 @@ class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() { shadeExpansionStateManager.onPanelExpansionChanged(1.0f, true, true, 0f) verifyZeroInteractions(action) } @Test fun testFromOpenState_becomeStateClose_enableDetector_shouldNotPostRunnable() { // STATE_OPEN is 2 shadeExpansionStateManager.updateState(2) detector.enable(action) shadeExpansionStateManager.onPanelExpansionChanged(0.5f, false, false, 0f) verifyZeroInteractions(action) Assert.assertEquals(true, shadeExpansionStateManager.isClosed()) } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt +27 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,13 @@ constructor( @Main private val mainExecutor: Executor, ) { private var action: Action? = null private var panelState: Int = -1 @MainThread fun enable(onPanelInteraction: Runnable) { if (action == null) { action = Action(onPanelInteraction) shadeExpansionStateManager.addStateListener(this::onPanelStateChanged) shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged) } else { Log.e(TAG, "Already enabled") Loading @@ -32,6 +34,8 @@ constructor( if (action != null) { Log.i(TAG, "Disable dectector") action = null panelState = -1 shadeExpansionStateManager.removeStateListener(this::onPanelStateChanged) shadeExpansionStateManager.removeExpansionListener(this::onPanelExpansionChanged) } } Loading @@ -40,13 +44,34 @@ constructor( private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) = mainExecutor.execute { action?.let { if (event.tracking || (event.expanded && event.fraction > 0)) { Log.i(TAG, "Detected panel interaction, event: $event") if (event.tracking || (event.expanded && event.fraction > 0 && panelState == 1)) { Log.i(TAG, "onPanelExpansionChanged, event: $event") it.onPanelInteraction.run() disable() } } } @AnyThread private fun onPanelStateChanged(state: Int) = mainExecutor.execute { // When device owner set screen lock type as Swipe, and install work profile with // pin/pattern/password & fingerprint or face, if work profile allow user to verify // by BP, it is possible that BP will be displayed when keyguard is closing, in this // case event.expanded = true and event.fraction > 0, so BP will be closed, adding // panel state into consideration is workaround^2, this workaround works because // onPanelStateChanged is earlier than onPanelExpansionChanged // we don't want to close BP in below case // // | Action | tracking | expanded | fraction | panelState | // | HeadsUp | NA | NA | NA | 1 | // | b/285111529 | false | true | > 0 | 2 | // Note: HeadsUp behavior was changed, so we can't got onPanelExpansionChanged now panelState = state Log.i(TAG, "onPanelStateChanged, state: $state") } } private data class Action(val onPanelInteraction: Runnable) Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt +13 −3 Original line number Diff line number Diff line Loading @@ -20,12 +20,12 @@ import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.shade.ShadeExpansionStateManager import org.junit.Assert import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions import org.mockito.junit.MockitoJUnit Loading Loading @@ -63,10 +63,10 @@ class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() { } @Test fun testEnableDetector_expandOnly_shouldPostRunnable() { fun testEnableDetector_expandOnly_shouldNotPostRunnable() { detector.enable(action) shadeExpansionStateManager.onPanelExpansionChanged(1.0f, true, false, 0f) verify(action).run() verifyZeroInteractions(action) } @Test Loading @@ -84,4 +84,14 @@ class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() { shadeExpansionStateManager.onPanelExpansionChanged(1.0f, true, true, 0f) verifyZeroInteractions(action) } @Test fun testFromOpenState_becomeStateClose_enableDetector_shouldNotPostRunnable() { // STATE_OPEN is 2 shadeExpansionStateManager.updateState(2) detector.enable(action) shadeExpansionStateManager.onPanelExpansionChanged(0.5f, false, false, 0f) verifyZeroInteractions(action) Assert.assertEquals(true, shadeExpansionStateManager.isClosed()) } }