Merge "Prevent alternateBouncer from consuming touches in new UdfpsOverlay" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
88c2ae44ec
@@ -51,6 +51,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
|
||||
import com.android.settingslib.udfps.UdfpsOverlayParams;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
@@ -778,7 +779,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUdfpsLocationChanged() {
|
||||
public void onUdfpsLocationChanged(UdfpsOverlayParams udfpsOverlayParams) {
|
||||
updateUdfpsConfig();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -148,6 +148,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
@NonNull private final WindowManager mWindowManager;
|
||||
@NonNull private final DisplayManager mDisplayManager;
|
||||
@Nullable private UdfpsController mUdfpsController;
|
||||
@Nullable private UdfpsOverlayParams mUdfpsOverlayParams;
|
||||
@Nullable private IUdfpsRefreshRateRequestCallback mUdfpsRefreshRateRequestCallback;
|
||||
@Nullable private SideFpsController mSideFpsController;
|
||||
@Nullable private UdfpsLogger mUdfpsLogger;
|
||||
@@ -806,6 +807,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
final FingerprintSensorPropertiesInternal udfpsProp = mUdfpsProps.get(0);
|
||||
|
||||
final Rect previousUdfpsBounds = mUdfpsBounds;
|
||||
final UdfpsOverlayParams previousUdfpsOverlayParams = mUdfpsOverlayParams;
|
||||
|
||||
mUdfpsBounds = udfpsProp.getLocation().getRect();
|
||||
mUdfpsBounds.scale(mScaleFactor);
|
||||
|
||||
@@ -815,7 +818,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
mCachedDisplayInfo.getNaturalWidth(), /* right */
|
||||
mCachedDisplayInfo.getNaturalHeight() /* botom */);
|
||||
|
||||
final UdfpsOverlayParams overlayParams = new UdfpsOverlayParams(
|
||||
mUdfpsOverlayParams = new UdfpsOverlayParams(
|
||||
mUdfpsBounds,
|
||||
overlayBounds,
|
||||
mCachedDisplayInfo.getNaturalWidth(),
|
||||
@@ -823,10 +826,11 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
mScaleFactor,
|
||||
mCachedDisplayInfo.rotation);
|
||||
|
||||
mUdfpsController.updateOverlayParams(udfpsProp, overlayParams);
|
||||
if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds)) {
|
||||
mUdfpsController.updateOverlayParams(udfpsProp, mUdfpsOverlayParams);
|
||||
if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds) || !Objects.equals(
|
||||
previousUdfpsOverlayParams, mUdfpsOverlayParams)) {
|
||||
for (Callback cb : mCallbacks) {
|
||||
cb.onUdfpsLocationChanged();
|
||||
cb.onUdfpsLocationChanged(mUdfpsOverlayParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1336,7 +1340,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
* On devices with UDFPS, this is always called alongside
|
||||
* {@link #onFingerprintLocationChanged}.
|
||||
*/
|
||||
default void onUdfpsLocationChanged() {}
|
||||
default void onUdfpsLocationChanged(UdfpsOverlayParams udfpsOverlayParams) {}
|
||||
|
||||
/**
|
||||
* Called when the location of the face unlock sensor (typically the front facing camera)
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback
|
||||
import com.android.keyguard.logging.KeyguardLogger
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.settingslib.udfps.UdfpsOverlayParams
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.animation.Interpolators
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
@@ -326,7 +327,7 @@ class AuthRippleController @Inject constructor(
|
||||
updateUdfpsDependentParams()
|
||||
}
|
||||
|
||||
override fun onUdfpsLocationChanged() {
|
||||
override fun onUdfpsLocationChanged(udfpsOverlayParams: UdfpsOverlayParams) {
|
||||
updateUdfpsDependentParams()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ import com.android.systemui.util.concurrency.Execution;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
import com.android.systemui.util.time.SystemClock;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -110,8 +112,6 @@ import java.util.concurrent.Executor;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
/**
|
||||
* Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events,
|
||||
* and toggles the UDFPS display mode.
|
||||
@@ -598,14 +598,20 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
|
||||
break;
|
||||
|
||||
case UNCHANGED:
|
||||
if (!isWithinSensorArea(mOverlay.getOverlayView(), event.getX(), event.getY(),
|
||||
true) && mActivePointerId == MotionEvent.INVALID_POINTER_ID
|
||||
&& event.getActionMasked() == MotionEvent.ACTION_DOWN
|
||||
&& mAlternateBouncerInteractor.isVisibleState()) {
|
||||
// No pointer on sensor, forward to keyguard if alternateBouncer is visible
|
||||
mKeyguardViewManager.onTouch(event);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
logBiometricTouch(processedTouch.getEvent(), data);
|
||||
|
||||
// We should only consume touches that are within the sensor. By returning "false" for
|
||||
// touches outside of the sensor, we let other UI components consume these events and act on
|
||||
// them appropriately.
|
||||
return processedTouch.getTouchData().isWithinSensor(mOverlayParams.getNativeSensorBounds());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.biometrics.domain.interactor
|
||||
|
||||
import android.view.MotionEvent
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.settingslib.udfps.UdfpsOverlayParams
|
||||
import com.android.systemui.biometrics.AuthController
|
||||
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
/** Encapsulates business logic for interacting with the UDFPS overlay. */
|
||||
@SysUISingleton
|
||||
class UdfpsOverlayInteractor
|
||||
@Inject
|
||||
constructor(private val authController: AuthController, @Application scope: CoroutineScope) {
|
||||
|
||||
/** Whether a touch should be intercepted or allowed to pass to the UdfpsOverlay */
|
||||
fun canInterceptTouchInUdfpsBounds(ev: MotionEvent): Boolean {
|
||||
val isUdfpsEnrolled = authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())
|
||||
val isWithinUdfpsOverlayBounds =
|
||||
udfpsOverlayParams.value.overlayBounds.contains(ev.rawX.toInt(), ev.rawY.toInt())
|
||||
return !isUdfpsEnrolled || !isWithinUdfpsOverlayBounds
|
||||
}
|
||||
|
||||
/** Returns the current udfpsOverlayParams */
|
||||
val udfpsOverlayParams: StateFlow<UdfpsOverlayParams> =
|
||||
ConflatedCallbackFlow.conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : AuthController.Callback {
|
||||
override fun onUdfpsLocationChanged(
|
||||
udfpsOverlayParams: UdfpsOverlayParams
|
||||
) {
|
||||
trySendWithFailureLogging(
|
||||
udfpsOverlayParams,
|
||||
TAG,
|
||||
"update udfpsOverlayParams"
|
||||
)
|
||||
}
|
||||
}
|
||||
authController.addCallback(callback)
|
||||
awaitClose { authController.removeCallback(callback) }
|
||||
}
|
||||
.stateIn(scope, started = SharingStarted.Eagerly, initialValue = UdfpsOverlayParams())
|
||||
|
||||
companion object {
|
||||
private const val TAG = "UdfpsOverlayInteractor"
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import com.android.keyguard.AuthKeyguardMessageArea;
|
||||
import com.android.keyguard.LockIconViewController;
|
||||
import com.android.keyguard.dagger.KeyguardBouncerComponent;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
@@ -86,7 +87,7 @@ public class NotificationShadeWindowViewController {
|
||||
private final PulsingGestureListener mPulsingGestureListener;
|
||||
private final NotificationInsetsController mNotificationInsetsController;
|
||||
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
private final UdfpsOverlayInteractor mUdfpsOverlayInteractor;
|
||||
private GestureDetector mPulsingWakeupGestureHandler;
|
||||
private View mBrightnessMirror;
|
||||
private boolean mTouchActive;
|
||||
@@ -134,6 +135,7 @@ public class NotificationShadeWindowViewController {
|
||||
KeyguardBouncerViewModel keyguardBouncerViewModel,
|
||||
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
|
||||
AlternateBouncerInteractor alternateBouncerInteractor,
|
||||
UdfpsOverlayInteractor udfpsOverlayInteractor,
|
||||
KeyguardTransitionInteractor keyguardTransitionInteractor,
|
||||
PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel
|
||||
) {
|
||||
@@ -156,6 +158,7 @@ public class NotificationShadeWindowViewController {
|
||||
mPulsingGestureListener = pulsingGestureListener;
|
||||
mNotificationInsetsController = notificationInsetsController;
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
mUdfpsOverlayInteractor = udfpsOverlayInteractor;
|
||||
|
||||
// This view is not part of the newly inflated expanded status bar.
|
||||
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
|
||||
@@ -240,7 +243,6 @@ public class NotificationShadeWindowViewController {
|
||||
|
||||
mFalsingCollector.onTouchEvent(ev);
|
||||
mPulsingWakeupGestureHandler.onTouchEvent(ev);
|
||||
mStatusBarKeyguardViewManager.onTouch(ev);
|
||||
if (mBrightnessMirror != null
|
||||
&& mBrightnessMirror.getVisibility() == View.VISIBLE) {
|
||||
// Disallow new pointers while the brightness mirror is visible. This is so that
|
||||
@@ -316,8 +318,8 @@ public class NotificationShadeWindowViewController {
|
||||
}
|
||||
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
// capture all touches if the alt auth bouncer is showing
|
||||
return true;
|
||||
// If using UDFPS, don't intercept touches that are within its overlay bounds
|
||||
return mUdfpsOverlayInteractor.canInterceptTouchInUdfpsBounds(ev);
|
||||
}
|
||||
|
||||
if (mLockIconViewController.onInterceptTouchEvent(ev)) {
|
||||
@@ -355,6 +357,7 @@ public class NotificationShadeWindowViewController {
|
||||
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
// eat the touch
|
||||
mStatusBarKeyguardViewManager.onTouch(ev);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.util.Pair;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.settingslib.udfps.UdfpsOverlayParams;
|
||||
import com.android.systemui.doze.util.BurnInHelperKt;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -107,7 +108,7 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
|
||||
Pair<Float, Point> udfps = setupUdfps();
|
||||
|
||||
// WHEN udfps location changes
|
||||
mAuthControllerCallback.onUdfpsLocationChanged();
|
||||
mAuthControllerCallback.onUdfpsLocationChanged(new UdfpsOverlayParams());
|
||||
mDelayableExecutor.runAllReady();
|
||||
|
||||
// THEN lock icon view location is updated with the same coordinates as auth controller vals
|
||||
|
||||
@@ -1223,6 +1223,44 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTouch_WithNewTouchDetection_forwardToKeyguard() throws RemoteException {
|
||||
final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
|
||||
0L);
|
||||
final TouchProcessorResult processorResultDown = new TouchProcessorResult.ProcessedTouch(
|
||||
InteractionEvent.UNCHANGED, -1 /* pointerOnSensorId */, touchData);
|
||||
|
||||
// Enable new touch detection.
|
||||
when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true);
|
||||
|
||||
// Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider.
|
||||
initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */);
|
||||
|
||||
// Configure UdfpsView to accept the ACTION_DOWN event
|
||||
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
|
||||
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(false);
|
||||
|
||||
// GIVEN that the overlay is showing and a11y touch exploration NOT enabled
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
|
||||
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
|
||||
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
|
||||
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
|
||||
|
||||
// WHEN ACTION_DOWN is received
|
||||
when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
|
||||
processorResultDown);
|
||||
MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
|
||||
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
|
||||
mBiometricExecutor.runAllReady();
|
||||
|
||||
// THEN the touch is forwarded to Keyguard
|
||||
verify(mStatusBarKeyguardViewManager).onTouch(downEvent);
|
||||
downEvent.recycle();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAodInterrupt_onAcquiredGood_fingerNoLongerDown() throws RemoteException {
|
||||
// GIVEN UDFPS overlay is showing
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.biometrics.domain.interactor
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.test.suitebuilder.annotation.SmallTest
|
||||
import android.view.MotionEvent
|
||||
import android.view.Surface
|
||||
import com.android.settingslib.udfps.UdfpsOverlayParams
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.biometrics.AuthController
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class UdfpsOverlayInteractorTest : SysuiTestCase() {
|
||||
|
||||
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
|
||||
|
||||
private lateinit var testScope: TestScope
|
||||
|
||||
@Mock private lateinit var authController: AuthController
|
||||
@Captor private lateinit var authControllerCallback: ArgumentCaptor<AuthController.Callback>
|
||||
|
||||
@Mock private lateinit var udfpsOverlayParams: UdfpsOverlayParams
|
||||
@Mock private lateinit var overlayBounds: Rect
|
||||
|
||||
private lateinit var underTest: UdfpsOverlayInteractor
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
testScope = TestScope(StandardTestDispatcher())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testShouldInterceptTouch() =
|
||||
testScope.runTest {
|
||||
createUdpfsOverlayInteractor()
|
||||
|
||||
// When fingerprint enrolled and touch is within bounds
|
||||
verify(authController).addCallback(authControllerCallback.capture())
|
||||
authControllerCallback.value.onUdfpsLocationChanged(udfpsOverlayParams)
|
||||
whenever(authController.isUdfpsEnrolled(anyInt())).thenReturn(true)
|
||||
whenever(udfpsOverlayParams.overlayBounds).thenReturn(overlayBounds)
|
||||
whenever(overlayBounds.contains(downEv.x.toInt(), downEv.y.toInt())).thenReturn(true)
|
||||
|
||||
runCurrent()
|
||||
|
||||
// Then touch should not be intercepted
|
||||
val canInterceptTrue = underTest.canInterceptTouchInUdfpsBounds(downEv)
|
||||
assertThat(canInterceptTrue).isFalse()
|
||||
|
||||
// When touch is outside of bounds
|
||||
whenever(overlayBounds.contains(downEv.x.toInt(), downEv.y.toInt())).thenReturn(false)
|
||||
|
||||
// Then touch should be intercepted
|
||||
val canInterceptFalse = underTest.canInterceptTouchInUdfpsBounds(downEv)
|
||||
assertThat(canInterceptFalse).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUdfpsOverlayParamsChange() =
|
||||
testScope.runTest {
|
||||
createUdpfsOverlayInteractor()
|
||||
val udfpsOverlayParams = collectLastValue(underTest.udfpsOverlayParams)
|
||||
runCurrent()
|
||||
|
||||
verify(authController).addCallback(authControllerCallback.capture())
|
||||
|
||||
// When udfpsLocationChanges in authcontroller
|
||||
authControllerCallback.value.onUdfpsLocationChanged(firstParams)
|
||||
|
||||
// Then the value in the interactor should be updated
|
||||
assertThat(udfpsOverlayParams()).isEqualTo(firstParams)
|
||||
}
|
||||
|
||||
private fun createUdpfsOverlayInteractor() {
|
||||
underTest = UdfpsOverlayInteractor(authController, testScope.backgroundScope)
|
||||
testScope.runCurrent()
|
||||
}
|
||||
}
|
||||
|
||||
private val firstParams =
|
||||
UdfpsOverlayParams(Rect(0, 0, 10, 10), Rect(0, 0, 10, 10), 1, 1, 1f, Surface.ROTATION_0)
|
||||
private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
|
||||
@@ -26,6 +26,7 @@ import com.android.keyguard.LockIconViewController
|
||||
import com.android.keyguard.dagger.KeyguardBouncerComponent
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
|
||||
import com.android.systemui.classifier.FalsingCollectorFake
|
||||
import com.android.systemui.dock.DockManager
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
|
||||
@@ -86,6 +87,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||
@Mock private lateinit var pulsingGestureListener: PulsingGestureListener
|
||||
@Mock private lateinit var notificationInsetsController: NotificationInsetsController
|
||||
@Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
|
||||
@Mock private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor
|
||||
@Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
|
||||
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
|
||||
@Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
|
||||
@@ -133,6 +135,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||
keyguardBouncerViewModel,
|
||||
keyguardBouncerComponentFactory,
|
||||
alternateBouncerInteractor,
|
||||
udfpsOverlayInteractor,
|
||||
keyguardTransitionInteractor,
|
||||
primaryBouncerToGoneTransitionViewModel,
|
||||
)
|
||||
@@ -264,6 +267,17 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||
assertThat(returnVal).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldInterceptTouchEvent_downEventAlternateBouncer_ignoreIfInUdfpsOverlay() {
|
||||
// Down event within udfpsOverlay bounds while alternateBouncer is showing
|
||||
whenever(udfpsOverlayInteractor.canInterceptTouchInUdfpsBounds(downEv)).thenReturn(false)
|
||||
whenever(alternateBouncerInteractor.isVisibleState()).thenReturn(true)
|
||||
|
||||
// Then touch should not be intercepted
|
||||
val shouldIntercept = interactionEventHandler.shouldInterceptTouchEvent(downEv)
|
||||
assertThat(shouldIntercept).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetBouncerContainer() {
|
||||
Mockito.clearInvocations(view)
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.android.keyguard.LockIconViewController;
|
||||
import com.android.keyguard.dagger.KeyguardBouncerComponent;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
|
||||
import com.android.systemui.classifier.FalsingCollectorFake;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
@@ -101,6 +102,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
@Mock private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
|
||||
@Mock private NotificationInsetsController mNotificationInsetsController;
|
||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock private UdfpsOverlayInteractor mUdfpsOverlayInteractor;
|
||||
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||
@Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
|
||||
|
||||
@@ -152,6 +154,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
mKeyguardBouncerViewModel,
|
||||
mKeyguardBouncerComponentFactory,
|
||||
mAlternateBouncerInteractor,
|
||||
mUdfpsOverlayInteractor,
|
||||
mKeyguardTransitionInteractor,
|
||||
mPrimaryBouncerToGoneTransitionViewModel
|
||||
);
|
||||
@@ -177,6 +180,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
// WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
|
||||
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mUdfpsOverlayInteractor.canInterceptTouchInUdfpsBounds(any())).thenReturn(true);
|
||||
when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
|
||||
|
||||
// THEN we should intercept touch
|
||||
|
||||
Reference in New Issue
Block a user