Remove dependency on ShadeExpansionStateManager from KeyguardBypassController
Part of the effort to remove ShadeExpansionStateManager dependencies in preparation for Flexiglass.
Bug: 280887022
Test: manually verified qs expanded values using logs
Test: passes existing tests
Change-Id: If1f13ff24bd8dbe09465e9f59ea6c52173cba418
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index 430b0e9..63591d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -21,12 +21,14 @@
import android.content.pm.PackageManager
import android.hardware.biometrics.BiometricSourceType
import android.provider.Settings
+import androidx.annotation.VisibleForTesting
import com.android.systemui.Dumpable
-import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.res.R
+import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm
@@ -35,6 +37,10 @@
import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.tuner.TunerService
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
import java.io.PrintWriter
import javax.inject.Inject
@@ -43,6 +49,7 @@
private val mKeyguardStateController: KeyguardStateController
private val statusBarStateController: StatusBarStateController
+ private val shadeRepository: ShadeRepository
private val devicePostureController: DevicePostureController
@BypassOverride private val bypassOverride: Int
private var hasFaceFeature: Boolean
@@ -107,16 +114,18 @@
@Inject
constructor(
context: Context,
+ @Application applicationScope: CoroutineScope,
tunerService: TunerService,
statusBarStateController: StatusBarStateController,
lockscreenUserManager: NotificationLockscreenUserManager,
keyguardStateController: KeyguardStateController,
- shadeExpansionStateManager: ShadeExpansionStateManager,
+ shadeRepository: ShadeRepository,
devicePostureController: DevicePostureController,
dumpManager: DumpManager
) {
this.mKeyguardStateController = keyguardStateController
this.statusBarStateController = statusBarStateController
+ this.shadeRepository = shadeRepository
this.devicePostureController = devicePostureController
bypassOverride = context.resources.getInteger(R.integer.config_face_unlock_bypass_override)
@@ -128,6 +137,7 @@
return
}
+
if (configFaceAuthSupportedPosture != DEVICE_POSTURE_UNKNOWN) {
devicePostureController.addCallback { posture ->
if (postureState != posture) {
@@ -137,7 +147,7 @@
}
}
- dumpManager.registerDumpable("KeyguardBypassController", this)
+ dumpManager.registerNormalDumpable("KeyguardBypassController", this)
statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
override fun onStateChanged(newState: Int) {
if (newState != StatusBarState.KEYGUARD) {
@@ -146,27 +156,36 @@
}
})
- shadeExpansionStateManager.addQsExpansionListener { isQsExpanded ->
- val changed = qsExpanded != isQsExpanded
- qsExpanded = isQsExpanded
- if (changed && !isQsExpanded) {
- maybePerformPendingUnlock()
- }
- }
+ listenForQsExpandedChange(applicationScope)
val dismissByDefault = if (context.resources.getBoolean(
- com.android.internal.R.bool.config_faceAuthDismissesKeyguard)) 1 else 0
+ com.android.internal.R.bool.config_faceAuthDismissesKeyguard)) 1 else 0
+
tunerService.addTunable({ key, _ ->
bypassEnabled = tunerService.getValue(key, dismissByDefault) != 0
}, Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD)
+
lockscreenUserManager.addUserChangedListener(
- object : NotificationLockscreenUserManager.UserChangedListener {
- override fun onUserChanged(userId: Int) {
- pendingUnlock = null
- }
- })
+ object : NotificationLockscreenUserManager.UserChangedListener {
+ override fun onUserChanged(userId: Int) {
+ pendingUnlock = null
+ }
+ })
}
+ @VisibleForTesting
+ fun listenForQsExpandedChange(scope: CoroutineScope) =
+ scope.launch {
+ shadeRepository.qsExpansion.map { it > 0f }.distinctUntilChanged()
+ .collect { isQsExpanded ->
+ val changed = qsExpanded != isQsExpanded
+ qsExpanded = isQsExpanded
+ if (changed && !isQsExpanded) {
+ maybePerformPendingUnlock()
+ }
+ }
+ }
+
private fun notifyListeners() = listeners.forEach { it.onBypassStateChanged(bypassEnabled) }
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
index ab441e3..6209f73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
@@ -20,11 +20,14 @@
import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.res.R
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.policy.DevicePostureController
import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED
@@ -34,6 +37,9 @@
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.tuner.TunerService
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -54,6 +60,10 @@
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class KeyguardBypassControllerTest : SysuiTestCase() {
+ private val utils = SceneTestUtils(this)
+ private val testScope = utils.testScope
+ private val featureFlags = FakeFeatureFlags()
+ private val shadeRepository = FakeShadeRepository()
private lateinit var keyguardBypassController: KeyguardBypassController
private lateinit var postureControllerCallback: DevicePostureController.Callback
@@ -61,10 +71,10 @@
@Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var lockscreenUserManager: NotificationLockscreenUserManager
@Mock private lateinit var keyguardStateController: KeyguardStateController
- @Mock private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
@Mock private lateinit var devicePostureController: DevicePostureController
@Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var packageManager: PackageManager
+
@Captor
private val postureCallbackCaptor =
ArgumentCaptor.forClass(DevicePostureController.Callback::class.java)
@@ -73,6 +83,8 @@
@Before
fun setUp() {
context.setMockPackageManager(packageManager)
+ featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
+
whenever(packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true)
whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true)
}
@@ -126,11 +138,12 @@
keyguardBypassController =
KeyguardBypassController(
context,
+ testScope.backgroundScope,
tunerService,
statusBarStateController,
lockscreenUserManager,
keyguardStateController,
- shadeExpansionStateManager,
+ shadeRepository,
devicePostureController,
dumpManager
)
@@ -267,4 +280,25 @@
assertThat(keyguardBypassController.bypassEnabled).isFalse()
}
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun qsExpansion_updates() {
+ testScope.runTest {
+ initKeyguardBypassController()
+ assertThat(keyguardBypassController.qsExpanded).isFalse()
+ val job = keyguardBypassController.listenForQsExpandedChange(this)
+ shadeRepository.setQsExpansion(0.5f)
+ runCurrent()
+
+ assertThat(keyguardBypassController.qsExpanded).isTrue()
+
+ shadeRepository.setQsExpansion(0f)
+ runCurrent()
+
+ assertThat(keyguardBypassController.qsExpanded).isFalse()
+
+ job.cancel()
+ }
+ }
}