Merge "4-1/ KeyguardBypassController listen for device posture change" into tm-qpr-dev

This commit is contained in:
Bill Lin
2023-01-13 09:04:42 +00:00
committed by Android (Google) Code Review
2 changed files with 291 additions and 3 deletions

View File

@@ -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. */

View File

@@ -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()
}
}