[multi-shade] Bouncer touch integration.
Connects multi-shade's touch interaction to the bouncer. On the lock screen such that dragging up when shades are collapsed brings up the bouncer. https://drive.google.com/file/d/1AiRelfhAg2QFY-EoHvHtG8V6KIzcST_g/view?usp=sharing Bug: 274159734 Flag: DUAL_SHADE Test: unit tests expanded for MultiShadeEventInteractor Test: manually verified that: 1. dragging up when shades are collapsed brings up the bouncer. 2. back gesture hides the bouncer, allowing a drag down to show the dual shades again. 3. unlocking the bouncer works as expected. Change-Id: I81118cb2ccba3bb2887def2568403198e7852c97
This commit is contained in:
@@ -19,13 +19,20 @@ package com.android.systemui.multishade.domain.interactor
|
||||
import android.content.Context
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewConfiguration
|
||||
import com.android.systemui.classifier.Classifier
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||
import com.android.systemui.keyguard.shared.model.KeyguardState
|
||||
import com.android.systemui.multishade.shared.math.isZero
|
||||
import com.android.systemui.multishade.shared.model.ProxiedInputModel
|
||||
import com.android.systemui.plugins.FalsingManager
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
/**
|
||||
@@ -39,15 +46,27 @@ class MultiShadeMotionEventInteractor
|
||||
constructor(
|
||||
@Application private val applicationContext: Context,
|
||||
@Application private val applicationScope: CoroutineScope,
|
||||
private val interactor: MultiShadeInteractor,
|
||||
private val multiShadeInteractor: MultiShadeInteractor,
|
||||
keyguardTransitionInteractor: KeyguardTransitionInteractor,
|
||||
private val bouncerInteractor: PrimaryBouncerInteractor,
|
||||
private val falsingManager: FalsingManager,
|
||||
) {
|
||||
|
||||
private val isAnyShadeExpanded: StateFlow<Boolean> =
|
||||
interactor.isAnyShadeExpanded.stateIn(
|
||||
multiShadeInteractor.isAnyShadeExpanded.stateIn(
|
||||
scope = applicationScope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = false,
|
||||
)
|
||||
private val isBouncerShowing: StateFlow<Boolean> =
|
||||
keyguardTransitionInteractor
|
||||
.transitionValue(state = KeyguardState.PRIMARY_BOUNCER)
|
||||
.map { !it.isZero() }
|
||||
.stateIn(
|
||||
scope = applicationScope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = false,
|
||||
)
|
||||
|
||||
private var interactionState: InteractionState? = null
|
||||
|
||||
@@ -65,6 +84,10 @@ constructor(
|
||||
return false
|
||||
}
|
||||
|
||||
if (isBouncerShowing.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
return when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
// Record where the pointer was placed and which pointer it was.
|
||||
@@ -75,7 +98,7 @@ constructor(
|
||||
currentY = event.y,
|
||||
pointerId = event.getPointerId(0),
|
||||
isDraggingHorizontally = false,
|
||||
isDraggingVertically = false,
|
||||
draggedVertically = Dragged.NONE,
|
||||
)
|
||||
|
||||
false
|
||||
@@ -85,16 +108,25 @@ constructor(
|
||||
val pointerIndex = event.findPointerIndex(it.pointerId)
|
||||
val currentX = event.getX(pointerIndex)
|
||||
val currentY = event.getY(pointerIndex)
|
||||
if (!it.isDraggingHorizontally && !it.isDraggingVertically) {
|
||||
val xDistanceTravelled = abs(currentX - it.initialX)
|
||||
val yDistanceTravelled = abs(currentY - it.initialY)
|
||||
if (!it.isDraggingHorizontally && it.draggedVertically == Dragged.NONE) {
|
||||
val xDistanceTravelled = currentX - it.initialX
|
||||
val yDistanceTravelled = currentY - it.initialY
|
||||
val touchSlop = ViewConfiguration.get(applicationContext).scaledTouchSlop
|
||||
interactionState =
|
||||
when {
|
||||
yDistanceTravelled > touchSlop ->
|
||||
it.copy(isDraggingVertically = true)
|
||||
xDistanceTravelled > touchSlop ->
|
||||
it.copy(isDraggingHorizontally = true)
|
||||
abs(yDistanceTravelled) > touchSlop ->
|
||||
it.copy(
|
||||
draggedVertically =
|
||||
if (yDistanceTravelled > 0) {
|
||||
Dragged.SHADE
|
||||
} else {
|
||||
Dragged.BOUNCER
|
||||
}
|
||||
)
|
||||
abs(xDistanceTravelled) > touchSlop ->
|
||||
it.copy(
|
||||
isDraggingHorizontally = true,
|
||||
)
|
||||
else -> interactionState
|
||||
}
|
||||
}
|
||||
@@ -124,7 +156,7 @@ constructor(
|
||||
return when (event.actionMasked) {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
interactionState?.let {
|
||||
if (it.isDraggingVertically) {
|
||||
if (it.draggedVertically != Dragged.NONE) {
|
||||
val pointerIndex = event.findPointerIndex(it.pointerId)
|
||||
val previousY = it.currentY
|
||||
val currentY = event.getY(pointerIndex)
|
||||
@@ -133,32 +165,48 @@ constructor(
|
||||
currentY = currentY,
|
||||
)
|
||||
|
||||
val yDragAmountPx = currentY - previousY
|
||||
if (yDragAmountPx != 0f) {
|
||||
interactor.sendProxiedInput(
|
||||
ProxiedInputModel.OnDrag(
|
||||
xFraction = event.x / viewWidthPx,
|
||||
yDragAmountPx = yDragAmountPx,
|
||||
)
|
||||
)
|
||||
when (it.draggedVertically) {
|
||||
Dragged.SHADE -> {
|
||||
val yDragAmountPx = currentY - previousY
|
||||
|
||||
if (yDragAmountPx != 0f) {
|
||||
multiShadeInteractor.sendProxiedInput(
|
||||
ProxiedInputModel.OnDrag(
|
||||
xFraction = event.x / viewWidthPx,
|
||||
yDragAmountPx = yDragAmountPx,
|
||||
)
|
||||
)
|
||||
}
|
||||
true
|
||||
}
|
||||
Dragged.BOUNCER -> {
|
||||
bouncerInteractor.show(isScrimmed = true)
|
||||
false
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
?: false
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (interactionState.isDraggingVertically()) {
|
||||
if (interactionState?.draggedVertically == Dragged.SHADE) {
|
||||
// We finished dragging. Record that so the multi-shade framework can issue a
|
||||
// fling, if the velocity reached in the drag was high enough, for example.
|
||||
interactor.sendProxiedInput(ProxiedInputModel.OnDragEnd)
|
||||
multiShadeInteractor.sendProxiedInput(ProxiedInputModel.OnDragEnd)
|
||||
|
||||
if (falsingManager.isFalseTouch(Classifier.SHADE_DRAG)) {
|
||||
multiShadeInteractor.collapseAll()
|
||||
}
|
||||
}
|
||||
|
||||
interactionState = null
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_CANCEL -> {
|
||||
if (interactionState.isDraggingVertically()) {
|
||||
if (interactionState?.draggedVertically == Dragged.SHADE) {
|
||||
// Our drag gesture was canceled by the system. This happens primarily in one of
|
||||
// two occasions: (a) the parent view has decided to intercept the gesture
|
||||
// itself and/or route it to a different child view or (b) the pointer has
|
||||
@@ -166,7 +214,15 @@ constructor(
|
||||
// we pass the cancellation event to the multi-shade framework to record it.
|
||||
// Doing that allows the multi-shade framework to know that the gesture ended to
|
||||
// allow new gestures to be accepted.
|
||||
interactor.sendProxiedInput(ProxiedInputModel.OnDragCancel)
|
||||
multiShadeInteractor.sendProxiedInput(ProxiedInputModel.OnDragCancel)
|
||||
|
||||
if (falsingManager.isFalseTouch(Classifier.SHADE_DRAG)) {
|
||||
multiShadeInteractor.collapseAll()
|
||||
}
|
||||
} else if (interactionState?.draggedVertically == Dragged.BOUNCER) {
|
||||
if (falsingManager.isFalseTouch(Classifier.BOUNCER_UNLOCK)) {
|
||||
bouncerInteractor.hide()
|
||||
}
|
||||
}
|
||||
|
||||
interactionState = null
|
||||
@@ -181,11 +237,23 @@ constructor(
|
||||
val initialY: Float,
|
||||
val currentY: Float,
|
||||
val pointerId: Int,
|
||||
/** Whether the current gesture is dragging horizontally. */
|
||||
val isDraggingHorizontally: Boolean,
|
||||
val isDraggingVertically: Boolean,
|
||||
/** The UI component that is being dragged vertically, if any. */
|
||||
val draggedVertically: Dragged,
|
||||
)
|
||||
|
||||
/** Enumerates the UI components that can be dragged by the user. */
|
||||
private enum class Dragged {
|
||||
/** The bouncer is being dragged by the user. */
|
||||
BOUNCER,
|
||||
/** A shade is being dragged by the user. */
|
||||
SHADE,
|
||||
/** No UI component is being dragged by the user. */
|
||||
NONE,
|
||||
}
|
||||
|
||||
private fun InteractionState?.isDraggingVertically(): Boolean {
|
||||
return this?.isDraggingVertically == true
|
||||
return this?.draggedVertically != Dragged.NONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +233,8 @@ import com.android.systemui.util.Utils;
|
||||
import com.android.systemui.util.time.SystemClock;
|
||||
import com.android.wm.shell.animation.FlingAnimationUtils;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -243,7 +245,6 @@ import java.util.function.Consumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlinx.coroutines.CoroutineDispatcher;
|
||||
|
||||
@CentralSurfacesComponent.CentralSurfacesScope
|
||||
@@ -387,6 +388,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
private KeyguardBottomAreaView mKeyguardBottomArea;
|
||||
private boolean mExpanding;
|
||||
private boolean mSplitShadeEnabled;
|
||||
private final boolean mMultiShadeEnabled;
|
||||
/** The bottom padding reserved for elements of the keyguard measuring notifications. */
|
||||
private float mKeyguardNotificationBottomPadding;
|
||||
/**
|
||||
@@ -851,6 +853,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
mFeatureFlags = featureFlags;
|
||||
mAnimateBack = mFeatureFlags.isEnabled(Flags.WM_SHADE_ANIMATE_BACK_GESTURE);
|
||||
mTrackpadGestureBack = mFeatureFlags.isEnabled(Flags.TRACKPAD_GESTURE_FEATURES);
|
||||
mMultiShadeEnabled = mFeatureFlags.isEnabled(Flags.DUAL_SHADE);
|
||||
mFalsingCollector = falsingCollector;
|
||||
mPowerManager = powerManager;
|
||||
mWakeUpCoordinator = coordinator;
|
||||
@@ -4018,8 +4021,11 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
* {@link #updateVisibility()}? That would allow us to make this method private.
|
||||
*/
|
||||
public void updatePanelExpansionAndVisibility() {
|
||||
mShadeExpansionStateManager.onPanelExpansionChanged(
|
||||
mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
|
||||
if (!mMultiShadeEnabled) {
|
||||
mShadeExpansionStateManager.onPanelExpansionChanged(
|
||||
mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
|
||||
}
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,14 @@ import android.view.MotionEvent
|
||||
import android.view.ViewConfiguration
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.classifier.FalsingManagerFake
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||
import com.android.systemui.keyguard.shared.model.KeyguardState
|
||||
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||
import com.android.systemui.keyguard.shared.model.TransitionStep
|
||||
import com.android.systemui.multishade.data.remoteproxy.MultiShadeInputProxy
|
||||
import com.android.systemui.multishade.data.repository.MultiShadeRepository
|
||||
import com.android.systemui.multishade.shared.model.ProxiedInputModel
|
||||
@@ -36,12 +43,18 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var bouncerInteractor: PrimaryBouncerInteractor
|
||||
|
||||
private lateinit var underTest: MultiShadeMotionEventInteractor
|
||||
|
||||
private lateinit var testScope: TestScope
|
||||
@@ -49,9 +62,13 @@ class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
private lateinit var repository: MultiShadeRepository
|
||||
private lateinit var interactor: MultiShadeInteractor
|
||||
private val touchSlop: Int = ViewConfiguration.get(context).scaledTouchSlop
|
||||
private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
|
||||
private lateinit var falsingManager: FalsingManagerFake
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
testScope = TestScope()
|
||||
motionEvents = mutableSetOf()
|
||||
|
||||
@@ -67,11 +84,19 @@ class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
repository = repository,
|
||||
inputProxy = inputProxy,
|
||||
)
|
||||
keyguardTransitionRepository = FakeKeyguardTransitionRepository()
|
||||
falsingManager = FalsingManagerFake()
|
||||
underTest =
|
||||
MultiShadeMotionEventInteractor(
|
||||
applicationContext = context,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
interactor = interactor,
|
||||
multiShadeInteractor = interactor,
|
||||
keyguardTransitionInteractor =
|
||||
KeyguardTransitionInteractor(
|
||||
repository = keyguardTransitionRepository,
|
||||
),
|
||||
bouncerInteractor = bouncerInteractor,
|
||||
falsingManager = falsingManager,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -201,6 +226,60 @@ class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_CANCEL))).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldIntercept_moveAboveTouchSlopAndUp_butBouncerShowing_returnsFalse() =
|
||||
testScope.runTest {
|
||||
keyguardTransitionRepository.sendTransitionStep(
|
||||
TransitionStep(
|
||||
from = KeyguardState.LOCKSCREEN,
|
||||
to = KeyguardState.PRIMARY_BOUNCER,
|
||||
value = 0.1f,
|
||||
transitionState = TransitionState.STARTED,
|
||||
)
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
|
||||
|
||||
assertThat(
|
||||
underTest.shouldIntercept(
|
||||
motionEvent(
|
||||
MotionEvent.ACTION_MOVE,
|
||||
y = touchSlop + 1f,
|
||||
)
|
||||
)
|
||||
)
|
||||
.isFalse()
|
||||
assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_UP))).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldIntercept_moveAboveTouchSlopAndCancel_butBouncerShowing_returnsFalse() =
|
||||
testScope.runTest {
|
||||
keyguardTransitionRepository.sendTransitionStep(
|
||||
TransitionStep(
|
||||
from = KeyguardState.LOCKSCREEN,
|
||||
to = KeyguardState.PRIMARY_BOUNCER,
|
||||
value = 0.1f,
|
||||
transitionState = TransitionState.STARTED,
|
||||
)
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
|
||||
|
||||
assertThat(
|
||||
underTest.shouldIntercept(
|
||||
motionEvent(
|
||||
MotionEvent.ACTION_MOVE,
|
||||
y = touchSlop + 1f,
|
||||
)
|
||||
)
|
||||
)
|
||||
.isFalse()
|
||||
assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_CANCEL))).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tap_doesNotSendProxiedInput() =
|
||||
testScope.runTest {
|
||||
@@ -233,7 +312,7 @@ class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragAboveTouchSlopAndUp() =
|
||||
fun dragShadeAboveTouchSlopAndUp() =
|
||||
testScope.runTest {
|
||||
val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
|
||||
val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
|
||||
@@ -277,7 +356,7 @@ class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragAboveTouchSlopAndCancel() =
|
||||
fun dragShadeAboveTouchSlopAndCancel() =
|
||||
testScope.runTest {
|
||||
val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
|
||||
val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
|
||||
@@ -320,6 +399,87 @@ class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragBouncerAboveTouchSlopAndUp_showsBouncer() =
|
||||
testScope.runTest {
|
||||
val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
|
||||
val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
|
||||
val singleShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.SINGLE))
|
||||
|
||||
underTest.shouldIntercept(
|
||||
motionEvent(
|
||||
MotionEvent.ACTION_DOWN,
|
||||
x = 100f, // left shade
|
||||
)
|
||||
)
|
||||
assertThat(leftShadeProxiedInput).isNull()
|
||||
assertThat(rightShadeProxiedInput).isNull()
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
|
||||
val yDragAmountPx = -(touchSlop + 1f) // dragging up
|
||||
val moveEvent =
|
||||
motionEvent(
|
||||
MotionEvent.ACTION_MOVE,
|
||||
x = 100f, // left shade
|
||||
y = yDragAmountPx,
|
||||
)
|
||||
assertThat(underTest.shouldIntercept(moveEvent)).isTrue()
|
||||
underTest.onTouchEvent(moveEvent, viewWidthPx = 1000)
|
||||
verify(bouncerInteractor).show(isScrimmed = true)
|
||||
assertThat(leftShadeProxiedInput).isNull()
|
||||
assertThat(rightShadeProxiedInput).isNull()
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
|
||||
val upEvent = motionEvent(MotionEvent.ACTION_UP)
|
||||
assertThat(underTest.shouldIntercept(upEvent)).isTrue()
|
||||
underTest.onTouchEvent(upEvent, viewWidthPx = 1000)
|
||||
verify(bouncerInteractor, never()).hide()
|
||||
assertThat(leftShadeProxiedInput).isNull()
|
||||
assertThat(rightShadeProxiedInput).isNull()
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragBouncerAboveTouchSlopAndCancel_falseTouch_showsThenHidesBouncer() =
|
||||
testScope.runTest {
|
||||
val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
|
||||
val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
|
||||
val singleShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.SINGLE))
|
||||
|
||||
underTest.shouldIntercept(
|
||||
motionEvent(
|
||||
MotionEvent.ACTION_DOWN,
|
||||
x = 900f, // right shade
|
||||
)
|
||||
)
|
||||
assertThat(leftShadeProxiedInput).isNull()
|
||||
assertThat(rightShadeProxiedInput).isNull()
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
|
||||
val yDragAmountPx = -(touchSlop + 1f) // drag up
|
||||
val moveEvent =
|
||||
motionEvent(
|
||||
MotionEvent.ACTION_MOVE,
|
||||
x = 900f, // right shade
|
||||
y = yDragAmountPx,
|
||||
)
|
||||
assertThat(underTest.shouldIntercept(moveEvent)).isTrue()
|
||||
underTest.onTouchEvent(moveEvent, viewWidthPx = 1000)
|
||||
verify(bouncerInteractor).show(isScrimmed = true)
|
||||
assertThat(leftShadeProxiedInput).isNull()
|
||||
assertThat(rightShadeProxiedInput).isNull()
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
|
||||
falsingManager.setIsFalseTouch(true)
|
||||
val cancelEvent = motionEvent(MotionEvent.ACTION_CANCEL)
|
||||
assertThat(underTest.shouldIntercept(cancelEvent)).isTrue()
|
||||
underTest.onTouchEvent(cancelEvent, viewWidthPx = 1000)
|
||||
verify(bouncerInteractor).hide()
|
||||
assertThat(leftShadeProxiedInput).isNull()
|
||||
assertThat(rightShadeProxiedInput).isNull()
|
||||
assertThat(singleShadeProxiedInput).isNull()
|
||||
}
|
||||
|
||||
private fun TestScope.motionEvent(
|
||||
action: Int,
|
||||
downTime: Long = currentTime,
|
||||
|
||||
@@ -27,10 +27,12 @@ import com.android.keyguard.dagger.KeyguardBouncerComponent
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.classifier.FalsingCollectorFake
|
||||
import com.android.systemui.classifier.FalsingManagerFake
|
||||
import com.android.systemui.dock.DockManager
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||
import com.android.systemui.keyguard.shared.model.TransitionStep
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
||||
@@ -67,8 +69,8 @@ import org.mockito.Mockito.anyFloat
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SmallTest
|
||||
@@ -170,7 +172,13 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||
MultiShadeMotionEventInteractor(
|
||||
applicationContext = context,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
interactor = multiShadeInteractor,
|
||||
multiShadeInteractor = multiShadeInteractor,
|
||||
keyguardTransitionInteractor =
|
||||
KeyguardTransitionInteractor(
|
||||
repository = FakeKeyguardTransitionRepository(),
|
||||
),
|
||||
bouncerInteractor = com.android.systemui.util.mockito.mock(),
|
||||
falsingManager = FalsingManagerFake(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -27,10 +27,12 @@ import com.android.keyguard.dagger.KeyguardBouncerComponent
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.classifier.FalsingCollectorFake
|
||||
import com.android.systemui.classifier.FalsingManagerFake
|
||||
import com.android.systemui.dock.DockManager
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
||||
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
|
||||
@@ -182,7 +184,13 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
|
||||
MultiShadeMotionEventInteractor(
|
||||
applicationContext = context,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
interactor = multiShadeInteractor,
|
||||
multiShadeInteractor = multiShadeInteractor,
|
||||
keyguardTransitionInteractor =
|
||||
KeyguardTransitionInteractor(
|
||||
repository = FakeKeyguardTransitionRepository(),
|
||||
),
|
||||
bouncerInteractor = mock(),
|
||||
falsingManager = FalsingManagerFake(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user