From 87f56277aad9173debceb432663e4feff4e9256d Mon Sep 17 00:00:00 2001 From: Vincent Wang Date: Wed, 7 Jun 2023 09:30:34 +0000 Subject: [PATCH] Fix work profile security challenge screen isn't properly shown Bug: 285111529 Test: 1. Use "Set up TestDPC..." launcher icon to create a work profile. After finishing you should see "personal" and "work" tabs in the all apps list in launcher. 2. Go to setting -> security & privacy -> more security & privacy -> untoggle "use one lock" to add a work password/pin/pattern. 3. Install and set up some app that can generate notifications into the work profile (e.g. a messaging app). 4. Turn the screen off and on to lock the profile. 5. Receive a notification with that work app, tap on it. Change-Id: I768f47369b61390580c6a2752edf7d1b53f9af9a --- .../AuthDialogPanelInteractionDetector.kt | 29 +++++++++++++++++-- .../AuthDialogPanelInteractionDetectorTest.kt | 16 ++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt index b72801d3b5fe4..5218537394dec 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt @@ -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") @@ -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) } } @@ -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) diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt index ef750be90b4bd..9cabd35cb1e59 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt @@ -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 @@ -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 @@ -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()) + } }