Merge "Dismiss Auth Biometric Prompt when expanding shade" into tm-dev

This commit is contained in:
Bill Lin
2022-05-10 10:44:47 +00:00
committed by Android (Google) Code Review
6 changed files with 167 additions and 7 deletions

View File

@@ -15,9 +15,11 @@
*/
package com.android.systemui.biometrics
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.phone.SystemUIDialogManager
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
/**
@@ -28,6 +30,7 @@ class UdfpsBpViewController(
statusBarStateController: StatusBarStateController,
panelExpansionStateManager: PanelExpansionStateManager,
systemUIDialogManager: SystemUIDialogManager,
val broadcastSender: BroadcastSender,
dumpManager: DumpManager
) : UdfpsAnimationViewController<UdfpsBpView>(
view,
@@ -37,4 +40,29 @@ class UdfpsBpViewController(
dumpManager
) {
override val tag = "UdfpsBpViewController"
private val bpPanelExpansionListener = PanelExpansionListener { event ->
// Notification shade can be expanded but not visible (fraction: 0.0), for example
// when a heads-up notification (HUN) is showing.
notificationShadeVisible = event.expanded && event.fraction > 0f
view.onExpansionChanged(event.fraction)
cancelAuth()
}
fun cancelAuth() {
if (shouldPauseAuth()) {
broadcastSender.closeSystemDialogs()
}
}
override fun onViewAttached() {
super.onViewAttached()
panelExpansionStateManager.addExpansionListener(bpPanelExpansionListener)
}
override fun onViewDetached() {
super.onViewDetached()
panelExpansionStateManager.removeExpansionListener(bpPanelExpansionListener)
}
}

View File

@@ -54,6 +54,7 @@ import com.android.internal.util.LatencyTracker;
import com.android.keyguard.ActiveUnlockConfig;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
@@ -125,6 +126,7 @@ public class UdfpsController implements DozeReceiver {
@NonNull private final UnlockedScreenOffAnimationController
mUnlockedScreenOffAnimationController;
@NonNull private final LatencyTracker mLatencyTracker;
@NonNull private final BroadcastSender mBroadcastSender;
@VisibleForTesting @NonNull final BiometricDisplayListener mOrientationListener;
@NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
@@ -205,7 +207,7 @@ public class UdfpsController implements DozeReceiver {
mUnlockedScreenOffAnimationController, mHalControlsIllumination,
mHbmProvider, requestId, reason, callback,
(view, event, fromUdfpsView) -> onTouch(requestId, event,
fromUdfpsView), mActivityLaunchAnimator)));
fromUdfpsView), mActivityLaunchAnimator, mBroadcastSender)));
}
@Override
@@ -574,7 +576,8 @@ public class UdfpsController implements DozeReceiver {
@NonNull SystemUIDialogManager dialogManager,
@NonNull LatencyTracker latencyTracker,
@NonNull ActivityLaunchAnimator activityLaunchAnimator,
@NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider) {
@NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider,
@NonNull BroadcastSender broadcastSender) {
mContext = context;
mExecution = execution;
mVibrator = vibrator;
@@ -604,6 +607,7 @@ public class UdfpsController implements DozeReceiver {
mLatencyTracker = latencyTracker;
mActivityLaunchAnimator = activityLaunchAnimator;
mAlternateTouchProvider = aternateTouchProvider.orElse(null);
mBroadcastSender = broadcastSender;
mOrientationListener = new BiometricDisplayListener(
context,

View File

@@ -41,6 +41,7 @@ import androidx.annotation.LayoutRes
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -83,7 +84,8 @@ class UdfpsControllerOverlay(
@ShowReason val requestReason: Int,
private val controllerCallback: IUdfpsOverlayControllerCallback,
private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
private val activityLaunchAnimator: ActivityLaunchAnimator
private val activityLaunchAnimator: ActivityLaunchAnimator,
private val broadcastSender: BroadcastSender
) {
/** The view, when [isShowing], or null. */
var overlayView: UdfpsView? = null
@@ -102,8 +104,8 @@ class UdfpsControllerOverlay(
fitInsetsTypes = 0
gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
flags =
(Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
flags = (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS
or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
// Avoid announcing window title.
accessibilityTitle = " "
@@ -221,6 +223,7 @@ class UdfpsControllerOverlay(
statusBarStateController,
panelExpansionStateManager,
dialogManager,
broadcastSender,
dumpManager
)
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2022 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.biometrics
import android.app.Instrumentation
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.StatusBarStateControllerImpl
import com.android.systemui.statusbar.phone.SystemUIDialogManager
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
import com.android.systemui.util.mockito.any
import org.junit.After
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.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class UdfpsBpViewControllerTest : SysuiTestCase() {
@JvmField @Rule var rule = MockitoJUnit.rule()
@Mock lateinit var dumpManager: DumpManager
@Mock lateinit var systemUIDialogManager: SystemUIDialogManager
@Mock lateinit var broadcastSender: BroadcastSender
@Mock lateinit var interactionJankMonitor: InteractionJankMonitor
@Mock lateinit var panelExpansionStateManager: PanelExpansionStateManager
private lateinit var instrumentation: Instrumentation
private lateinit var uiEventLogger: UiEventLoggerFake
private lateinit var udfpsBpView: UdfpsBpView
private lateinit var statusBarStateController: StatusBarStateControllerImpl
private lateinit var udfpsBpViewController: UdfpsBpViewController
@Before
fun setup() {
instrumentation = getInstrumentation()
instrumentation.runOnMainSync { createUdfpsView() }
instrumentation.waitForIdleSync()
uiEventLogger = UiEventLoggerFake()
statusBarStateController =
StatusBarStateControllerImpl(uiEventLogger, dumpManager, interactionJankMonitor)
udfpsBpViewController = UdfpsBpViewController(
udfpsBpView,
statusBarStateController,
panelExpansionStateManager,
systemUIDialogManager,
broadcastSender,
dumpManager)
udfpsBpViewController.init()
}
@After
fun tearDown() {
if (udfpsBpViewController.isAttachedToWindow) {
instrumentation.runOnMainSync { ViewUtils.detachView(udfpsBpView) }
instrumentation.waitForIdleSync()
}
}
private fun createUdfpsView() {
context.setTheme(R.style.Theme_AppCompat)
context.orCreateTestableResources.addOverride(
com.android.internal.R.integer.config_udfps_illumination_transition_ms, 0)
udfpsBpView = UdfpsBpView(context, null)
}
@Test
fun addExpansionListener() {
instrumentation.runOnMainSync { ViewUtils.attachView(udfpsBpView) }
instrumentation.waitForIdleSync()
// Both UdfpsBpViewController & UdfpsAnimationViewController add listener
verify(panelExpansionStateManager, times(2)).addExpansionListener(any())
}
@Test
fun removeExpansionListener() {
instrumentation.runOnMainSync { ViewUtils.attachView(udfpsBpView) }
instrumentation.waitForIdleSync()
instrumentation.runOnMainSync { ViewUtils.detachView(udfpsBpView) }
instrumentation.waitForIdleSync()
// Both UdfpsBpViewController & UdfpsAnimationViewController remove listener
verify(panelExpansionStateManager, times(2)).removeExpansionListener(any())
}
}

View File

@@ -40,6 +40,7 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -102,6 +103,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
@Mock private lateinit var udfpsView: UdfpsView
@Mock private lateinit var udfpsEnrollView: UdfpsEnrollView
@Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
@Mock private lateinit var broadcastSender: BroadcastSender
@Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
@@ -131,7 +133,8 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
configurationController, systemClock, keyguardStateController,
unlockedScreenOffAnimationController, HAL_CONTROLS_ILLUMINATION, hbmProvider,
REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator)
REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator,
broadcastSender)
block()
}

View File

@@ -66,6 +66,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
@@ -186,6 +187,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
private ActivityLaunchAnimator mActivityLaunchAnimator;
@Mock
private AlternateUdfpsTouchProvider mAlternateTouchProvider;
@Mock
private BroadcastSender mBroadcastSender;
// Capture listeners so that they can be used to send events
@Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor;
@@ -261,7 +264,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mSystemUIDialogManager,
mLatencyTracker,
mActivityLaunchAnimator,
Optional.of(mAlternateTouchProvider));
Optional.of(mAlternateTouchProvider),
mBroadcastSender);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());