Merge "4-1/ KeyguardBypassController listen for device posture change" into tm-qpr-dev
This commit is contained in:
@@ -30,6 +30,9 @@ import com.android.systemui.shade.ShadeExpansionStateManager
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||
import com.android.systemui.statusbar.StatusBarState
|
||||
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.tuner.TunerService
|
||||
import java.io.PrintWriter
|
||||
@@ -40,11 +43,19 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
|
||||
|
||||
private val mKeyguardStateController: KeyguardStateController
|
||||
private val statusBarStateController: StatusBarStateController
|
||||
private val devicePostureController: DevicePostureController
|
||||
@BypassOverride private val bypassOverride: Int
|
||||
private var hasFaceFeature: Boolean
|
||||
@DevicePostureInt private val configFaceAuthSupportedPosture: Int
|
||||
@DevicePostureInt private var postureState: Int = DEVICE_POSTURE_UNKNOWN
|
||||
private var pendingUnlock: PendingUnlock? = null
|
||||
private val listeners = mutableListOf<OnBypassStateChangedListener>()
|
||||
|
||||
private val postureCallback = DevicePostureController.Callback { posture ->
|
||||
if (postureState != posture) {
|
||||
postureState = posture
|
||||
notifyListeners()
|
||||
}
|
||||
}
|
||||
private val faceAuthEnabledChangedCallback = object : KeyguardStateController.Callback {
|
||||
override fun onFaceAuthEnabledChanged() = notifyListeners()
|
||||
}
|
||||
@@ -86,7 +97,8 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
|
||||
FACE_UNLOCK_BYPASS_NEVER -> false
|
||||
else -> field
|
||||
}
|
||||
return enabled && mKeyguardStateController.isFaceAuthEnabled
|
||||
return enabled && mKeyguardStateController.isFaceAuthEnabled &&
|
||||
isPostureAllowedForFaceAuth()
|
||||
}
|
||||
private set(value) {
|
||||
field = value
|
||||
@@ -106,18 +118,31 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
|
||||
lockscreenUserManager: NotificationLockscreenUserManager,
|
||||
keyguardStateController: KeyguardStateController,
|
||||
shadeExpansionStateManager: ShadeExpansionStateManager,
|
||||
devicePostureController: DevicePostureController,
|
||||
dumpManager: DumpManager
|
||||
) {
|
||||
this.mKeyguardStateController = keyguardStateController
|
||||
this.statusBarStateController = statusBarStateController
|
||||
this.devicePostureController = devicePostureController
|
||||
|
||||
bypassOverride = context.resources.getInteger(R.integer.config_face_unlock_bypass_override)
|
||||
configFaceAuthSupportedPosture =
|
||||
context.resources.getInteger(R.integer.config_face_auth_supported_posture)
|
||||
|
||||
hasFaceFeature = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)
|
||||
hasFaceFeature = context.packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)
|
||||
if (!hasFaceFeature) {
|
||||
return
|
||||
}
|
||||
|
||||
if (configFaceAuthSupportedPosture != DEVICE_POSTURE_UNKNOWN) {
|
||||
devicePostureController.addCallback { posture ->
|
||||
if (postureState != posture) {
|
||||
postureState = posture
|
||||
notifyListeners()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dumpManager.registerDumpable("KeyguardBypassController", this)
|
||||
statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
|
||||
override fun onStateChanged(newState: Int) {
|
||||
@@ -203,6 +228,13 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
|
||||
pendingUnlock = null
|
||||
}
|
||||
|
||||
fun isPostureAllowedForFaceAuth(): Boolean {
|
||||
return when (configFaceAuthSupportedPosture) {
|
||||
DEVICE_POSTURE_UNKNOWN -> true
|
||||
else -> (postureState == configFaceAuthSupportedPosture)
|
||||
}
|
||||
}
|
||||
|
||||
override fun dump(pw: PrintWriter, args: Array<out String>) {
|
||||
pw.println("KeyguardBypassController:")
|
||||
if (pendingUnlock != null) {
|
||||
@@ -219,6 +251,7 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
|
||||
pw.println(" launchingAffordance: $launchingAffordance")
|
||||
pw.println(" qSExpanded: $qsExpanded")
|
||||
pw.println(" hasFaceFeature: $hasFaceFeature")
|
||||
pw.println(" postureState: $postureState")
|
||||
}
|
||||
|
||||
/** Registers a listener for bypass state changes. */
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.phone
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.test.suitebuilder.annotation.SmallTest
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.shade.ShadeExpansionStateManager
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_FLIPPED
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED
|
||||
import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.tuner.TunerService
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@TestableLooper.RunWithLooper
|
||||
class KeyguardBypassControllerTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var keyguardBypassController: KeyguardBypassController
|
||||
private lateinit var postureControllerCallback: DevicePostureController.Callback
|
||||
@Mock private lateinit var tunerService: TunerService
|
||||
@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)
|
||||
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context.setMockPackageManager(packageManager)
|
||||
whenever(packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true)
|
||||
whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
reset(devicePostureController)
|
||||
reset(keyguardStateController)
|
||||
}
|
||||
|
||||
private fun defaultConfigPostureClosed() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_auth_supported_posture,
|
||||
DEVICE_POSTURE_CLOSED
|
||||
)
|
||||
initKeyguardBypassController()
|
||||
verify(devicePostureController).addCallback(postureCallbackCaptor.capture())
|
||||
postureControllerCallback = postureCallbackCaptor.value
|
||||
}
|
||||
|
||||
private fun defaultConfigPostureOpened() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_auth_supported_posture,
|
||||
DEVICE_POSTURE_OPENED
|
||||
)
|
||||
initKeyguardBypassController()
|
||||
verify(devicePostureController).addCallback(postureCallbackCaptor.capture())
|
||||
postureControllerCallback = postureCallbackCaptor.value
|
||||
}
|
||||
|
||||
private fun defaultConfigPostureFlipped() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_auth_supported_posture,
|
||||
DEVICE_POSTURE_FLIPPED
|
||||
)
|
||||
initKeyguardBypassController()
|
||||
verify(devicePostureController).addCallback(postureCallbackCaptor.capture())
|
||||
postureControllerCallback = postureCallbackCaptor.value
|
||||
}
|
||||
|
||||
private fun defaultConfigPostureUnknown() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_auth_supported_posture,
|
||||
DEVICE_POSTURE_UNKNOWN
|
||||
)
|
||||
initKeyguardBypassController()
|
||||
verify(devicePostureController, never()).addCallback(postureCallbackCaptor.capture())
|
||||
}
|
||||
|
||||
private fun initKeyguardBypassController() {
|
||||
keyguardBypassController =
|
||||
KeyguardBypassController(
|
||||
context,
|
||||
tunerService,
|
||||
statusBarStateController,
|
||||
lockscreenUserManager,
|
||||
keyguardStateController,
|
||||
shadeExpansionStateManager,
|
||||
devicePostureController,
|
||||
dumpManager
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureClosed_matchState_isPostureAllowedForFaceAuth_returnTrue() {
|
||||
defaultConfigPostureClosed()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureOpen_matchState_isPostureAllowedForFaceAuth_returnTrue() {
|
||||
defaultConfigPostureOpened()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureFlipped_matchState_isPostureAllowedForFaceAuth_returnTrue() {
|
||||
defaultConfigPostureFlipped()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_FLIPPED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureClosed_changeOpened_isPostureAllowedForFaceAuth_returnFalse() {
|
||||
defaultConfigPostureClosed()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureClosed_changeFlipped_isPostureAllowedForFaceAuth_returnFalse() {
|
||||
defaultConfigPostureClosed()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_FLIPPED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureOpened_changeClosed_isPostureAllowedForFaceAuth_returnFalse() {
|
||||
defaultConfigPostureOpened()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureOpened_changeFlipped_isPostureAllowedForFaceAuth_returnFalse() {
|
||||
defaultConfigPostureOpened()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_FLIPPED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureFlipped_changeClosed_isPostureAllowedForFaceAuth_returnFalse() {
|
||||
defaultConfigPostureFlipped()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configDevicePostureFlipped_changeOpened_isPostureAllowedForFaceAuth_returnFalse() {
|
||||
defaultConfigPostureFlipped()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
|
||||
|
||||
assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultConfigPostureClosed_canOverrideByPassAlways_shouldReturnFalse() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_unlock_bypass_override,
|
||||
1 /* FACE_UNLOCK_BYPASS_ALWAYS */
|
||||
)
|
||||
|
||||
defaultConfigPostureClosed()
|
||||
|
||||
postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
|
||||
|
||||
assertThat(keyguardBypassController.bypassEnabled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultConfigPostureUnknown_canNotOverrideByPassAlways_shouldReturnTrue() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_unlock_bypass_override,
|
||||
1 /* FACE_UNLOCK_BYPASS_ALWAYS */
|
||||
)
|
||||
|
||||
defaultConfigPostureUnknown()
|
||||
|
||||
assertThat(keyguardBypassController.bypassEnabled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultConfigPostureUnknown_canNotOverrideByPassNever_shouldReturnFalse() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.integer.config_face_unlock_bypass_override,
|
||||
2 /* FACE_UNLOCK_BYPASS_NEVER */
|
||||
)
|
||||
|
||||
defaultConfigPostureUnknown()
|
||||
|
||||
assertThat(keyguardBypassController.bypassEnabled).isFalse()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user