diff options
| author | 2023-06-13 16:11:05 -0400 | |
|---|---|---|
| committer | 2023-06-14 14:58:04 -0400 | |
| commit | 43766b71dea3459d5ac376ffb2036a51a3848e1a (patch) | |
| tree | 5f6d1f454a9a7df21debb4bf9e2f8506669e80bc | |
| parent | 176cef8731b45cd7fa1d7ae74eb22fb2f0371ec9 (diff) | |
Extract back handling from CentralSurfaces
Test: added new test
Bug: 249277686
Change-Id: I445d11724a24769c59029b8d66653f678200dfc0
13 files changed, 290 insertions, 105 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java index 281067da6757..bc12aeebd84c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java @@ -119,6 +119,14 @@ public interface KeyguardViewController { boolean isUnlockWithWallpaper(); /** + * @return Whether the bouncer over dream is showing. Note that the bouncer over dream is + * handled independently of the rest of the notification panel. As a result, setting this state + * via {@link CentralSurfaces#setBouncerShowing(boolean)} leads to unintended side effects from + * states modified behind the dream. + */ + boolean isBouncerShowingOverDream(); + + /** * @return Whether subtle animation should be used for unlocking the device. */ boolean shouldSubtleWindowAnimationsForUnlock(); diff --git a/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt new file mode 100644 index 000000000000..3c74bf484e98 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/back/domain/interactor/BackActionInteractor.kt @@ -0,0 +1,77 @@ +/* + * 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.back.domain.interactor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.shade.QuickSettingsController +import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.ShadeViewController +import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager +import javax.inject.Inject + +/** Handles requests to go back either from a button or gesture. */ +@SysUISingleton +class BackActionInteractor +@Inject +constructor( + private val statusBarStateController: StatusBarStateController, + private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager, + private val shadeController: ShadeController +) { + private lateinit var shadeViewController: ShadeViewController + private lateinit var qsController: QuickSettingsController + + fun setup(qsController: QuickSettingsController, svController: ShadeViewController) { + this.qsController = qsController + this.shadeViewController = svController + } + + fun shouldBackBeHandled(): Boolean { + return statusBarStateController.state != StatusBarState.KEYGUARD && + statusBarStateController.state != StatusBarState.SHADE_LOCKED && + !statusBarKeyguardViewManager.isBouncerShowingOverDream + } + + fun onBackRequested(): Boolean { + if (statusBarKeyguardViewManager.canHandleBackPressed()) { + statusBarKeyguardViewManager.onBackPressed() + return true + } + if (qsController.isCustomizing) { + qsController.closeQsCustomizer() + return true + } + if (qsController.expanded) { + shadeViewController.animateCollapseQs(false) + return true + } + if (shadeViewController.closeUserSwitcherIfOpen()) { + return true + } + if (shouldBackBeHandled()) { + if (shadeViewController.canBeCollapsed()) { + // this is the Shade dismiss animation, so make sure QQS closes when it ends. + shadeViewController.onBackPressed() + shadeController.animateCollapseShade() + } + return true + } + return false + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index c4b74fc4ddf8..ade59d7d85bb 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -40,18 +40,19 @@ import com.android.keyguard.KeyguardMessageAreaController; import com.android.keyguard.LockIconViewController; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.R; +import com.android.systemui.back.domain.interactor.BackActionInteractor; +import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; +import com.android.systemui.bouncer.ui.binder.KeyguardBouncerViewBinder; +import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.compose.ComposeFacade; import com.android.systemui.dock.DockManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; -import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; -import com.android.systemui.bouncer.ui.binder.KeyguardBouncerViewBinder; -import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel; import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel; import com.android.systemui.log.BouncerLogger; import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor; @@ -111,6 +112,7 @@ public class NotificationShadeWindowViewController { private NotificationStackScrollLayout mStackScrollLayout; private PhoneStatusBarViewController mStatusBarViewController; private final CentralSurfaces mService; + private final BackActionInteractor mBackActionInteractor; private final NotificationShadeWindowController mNotificationShadeWindowController; private DragDownHelper mDragDownHelper; private boolean mExpandingBelowNotch; @@ -144,6 +146,7 @@ public class NotificationShadeWindowViewController { StatusBarWindowStateController statusBarWindowStateController, LockIconViewController lockIconViewController, CentralSurfaces centralSurfaces, + BackActionInteractor backActionInteractor, NotificationShadeWindowController controller, Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @@ -173,6 +176,7 @@ public class NotificationShadeWindowViewController { mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mStatusBarWindowStateController = statusBarWindowStateController; mLockIconViewController = lockIconViewController; + mBackActionInteractor = backActionInteractor; mLockIconViewController.init(); mService = centralSurfaces; mNotificationShadeWindowController = controller; @@ -443,7 +447,7 @@ public class NotificationShadeWindowViewController { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_BACK: if (!down) { - mService.onBackPressed(); + mBackActionInteractor.onBackRequested(); } return true; case KeyEvent.KEYCODE_MENU: diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt index 5ac36bfc374f..8d5c30b51677 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt @@ -36,33 +36,12 @@ interface ShadeSurface : ShadeViewController { headsUpManager: HeadsUpManagerPhone ) - /** - * Animate QS collapse by flinging it. If QS is expanded, it will collapse into QQS and stop. If - * in split shade, it will collapse the whole shade. - * - * @param fullyCollapse Do not stop when QS becomes QQS. Fling until QS isn't visible anymore. - */ - fun animateCollapseQs(fullyCollapse: Boolean) - - /** Returns whether the shade can be collapsed. */ - fun canBeCollapsed(): Boolean - /** Cancels any pending collapses. */ fun cancelPendingCollapse() /** Cancels the views current animation. */ fun cancelAnimation() - /** - * Close the keyguard user switcher if it is open and capable of closing. - * - * Has no effect if user switcher isn't supported, if the user switcher is already closed, or if - * the user switcher uses "simple" mode. The simple user switcher cannot be closed. - * - * @return true if the keyguard user switcher was open, and is now closed - */ - fun closeUserSwitcherIfOpen(): Boolean - /** Input focus transfer is about to happen. */ fun startWaitingForExpandGesture() @@ -116,9 +95,6 @@ interface ShadeSurface : ShadeViewController { /** Sets the view's alpha to max. */ fun resetAlpha() - /** Called when Back gesture has been committed (i.e. a back event has definitely occurred) */ - fun onBackPressed() - /** Sets progress of the predictive back animation. */ fun onBackProgressed(progressFraction: Float) diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt index 9c80e0250ee9..05d2bc64c535 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt @@ -77,6 +77,17 @@ interface ShadeViewController { /** Collapses the shade with an animation duration in milliseconds. */ fun collapseWithDuration(animationDuration: Int) + /** + * Animate QS collapse by flinging it. If QS is expanded, it will collapse into QQS and stop. If + * in split shade, it will collapse the whole shade. + * + * @param fullyCollapse Do not stop when QS becomes QQS. Fling until QS isn't visible anymore. + */ + fun animateCollapseQs(fullyCollapse: Boolean) + + /** Returns whether the shade can be collapsed. */ + fun canBeCollapsed(): Boolean + /** Returns whether the shade is in the process of collapsing. */ val isCollapsing: Boolean @@ -126,6 +137,19 @@ interface ShadeViewController { /** Sets the amount of progress in the status bar launch animation. */ fun applyLaunchAnimationProgress(linearProgress: Float) + /** + * Close the keyguard user switcher if it is open and capable of closing. + * + * Has no effect if user switcher isn't supported, if the user switcher is already closed, or if + * the user switcher uses "simple" mode. The simple user switcher cannot be closed. + * + * @return true if the keyguard user switcher was open, and is now closed + */ + fun closeUserSwitcherIfOpen(): Boolean + + /** Called when Back gesture has been committed (i.e. a back event has definitely occurred) */ + fun onBackPressed() + /** Sets whether the status bar launch animation is currently running. */ fun setIsLaunchAnimationRunning(running: Boolean) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index 18d8050f9a36..01c00b6308cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -302,8 +302,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { /** Should the keyguard be hidden immediately in response to a back press/gesture. */ boolean shouldKeyguardHideImmediately(); - boolean onBackPressed(); - boolean onSpacePressed(); void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction, @@ -320,8 +318,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { void setBouncerShowing(boolean bouncerShowing); - void setBouncerShowingOverDream(boolean bouncerShowingOverDream); - int getWakefulnessState(); boolean isScreenFullyOff(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 1396d8efc7af..7496df956c92 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -135,6 +135,7 @@ import com.android.systemui.R; import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.assist.AssistManager; +import com.android.systemui.back.domain.interactor.BackActionInteractor; import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -600,6 +601,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final ViewMediatorCallback mKeyguardViewMediatorCallback; private final ScrimController mScrimController; protected DozeScrimController mDozeScrimController; + private final BackActionInteractor mBackActionInteractor; private final Executor mUiBgExecutor; protected boolean mDozing; @@ -660,17 +662,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final InteractionJankMonitor mJankMonitor; /** Existing callback that handles back gesture invoked for the Shade. */ - private final OnBackInvokedCallback mOnBackInvokedCallback = () -> { - if (DEBUG) { - Log.d(TAG, "mOnBackInvokedCallback() called"); - } - onBackPressed(); - }; - - private boolean shouldBackBeHandled() { - return (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED - && !isBouncerShowingOverDream()); - } + private final OnBackInvokedCallback mOnBackInvokedCallback; /** * New callback that handles back gesture invoked, cancel, progress @@ -680,12 +672,12 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final OnBackAnimationCallback mOnBackAnimationCallback = new OnBackAnimationCallback() { @Override public void onBackInvoked() { - onBackPressed(); + mBackActionInteractor.onBackRequested(); } @Override public void onBackProgressed(BackEvent event) { - if (shouldBackBeHandled()) { + if (mBackActionInteractor.shouldBackBeHandled()) { if (mShadeSurface.canBeCollapsed()) { float fraction = event.getProgress(); mShadeSurface.onBackProgressed(fraction); @@ -756,6 +748,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { Lazy<BiometricUnlockController> biometricUnlockControllerLazy, AuthRippleController authRippleController, DozeServiceHost dozeServiceHost, + BackActionInteractor backActionInteractor, PowerManager powerManager, ScreenPinningRequest screenPinningRequest, DozeScrimController dozeScrimController, @@ -815,6 +808,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mKeyguardBypassController = keyguardBypassController; mKeyguardStateController = keyguardStateController; mHeadsUpManager = headsUpManagerPhone; + mBackActionInteractor = backActionInteractor; mKeyguardIndicationController = keyguardIndicationController; mStatusBarTouchableRegionManager = statusBarTouchableRegionManager; mFalsingCollector = falsingCollector; @@ -935,6 +929,12 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } // Based on teamfood flag, enable predictive back animation for the Shade. mAnimateBack = mFeatureFlags.isEnabled(Flags.WM_SHADE_ANIMATE_BACK_GESTURE); + mOnBackInvokedCallback = () -> { + if (DEBUG) { + Log.d(TAG, "mOnBackInvokedCallback() called"); + } + mBackActionInteractor.onBackRequested(); + }; } private void initBubbles(Bubbles bubbles) { @@ -1654,6 +1654,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mStackScrollerController = mCentralSurfacesComponent.getNotificationStackScrollLayoutController(); mQsController = mCentralSurfacesComponent.getQuickSettingsController(); + mBackActionInteractor.setup(mQsController, mShadeSurface); mStackScroller = mStackScrollerController.getView(); mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer(); mPresenter = mCentralSurfacesComponent.getNotificationPresenter(); @@ -2749,7 +2750,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { case KeyEvent.KEYCODE_BACK: if (mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.dispatchBackKeyEventPreIme()) { - return onBackPressed(); + return mBackActionInteractor.onBackRequested(); } } return false; @@ -2789,34 +2790,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } @Override - public boolean onBackPressed() { - if (mStatusBarKeyguardViewManager.canHandleBackPressed()) { - mStatusBarKeyguardViewManager.onBackPressed(); - return true; - } - if (mQsController.isCustomizing()) { - mQsController.closeQsCustomizer(); - return true; - } - if (mQsController.getExpanded()) { - mShadeSurface.animateCollapseQs(false); - return true; - } - if (mShadeSurface.closeUserSwitcherIfOpen()) { - return true; - } - if (shouldBackBeHandled()) { - if (mShadeSurface.canBeCollapsed()) { - // this is the Shade dismiss animation, so make sure QQS closes when it ends. - mShadeSurface.onBackPressed(); - mShadeController.animateCollapseShade(); - } - return true; - } - return false; - } - - @Override public boolean onSpacePressed() { if (mDeviceInteractive && mState != StatusBarState.SHADE) { mShadeController.animateCollapseShadeForced(); @@ -2943,17 +2916,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } /** - * Sets whether the bouncer over dream is showing. Note that the bouncer over dream is handled - * independently of the rest of the notification panel. As a result, setting this state via - * {@link #setBouncerShowing(boolean)} leads to unintended side effects from states modified - * behind the dream. - */ - @Override - public void setBouncerShowingOverDream(boolean bouncerShowingOverDream) { - mBouncerShowingOverDream = bouncerShowingOverDream; - } - - /** * Propagate the bouncer state to status bar components. * * Separate from {@link #setBouncerShowing} because we sometimes re-create the status bar and diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index bb4aacbe4cab..e63875b92b64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -53,16 +53,16 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; +import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor; +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; +import com.android.systemui.bouncer.ui.BouncerView; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dock.DockManager; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; -import com.android.systemui.bouncer.ui.BouncerView; -import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; -import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor; -import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; -import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.TaskbarDelegate; @@ -144,6 +144,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb // Local cache of expansion events, to avoid duplicates private float mFraction = -1f; private boolean mTracking = false; + private boolean mBouncerShowingOverDream; private final PrimaryBouncerExpansionCallback mExpansionCallback = new PrimaryBouncerExpansionCallback() { @@ -182,8 +183,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb @Override public void onVisibilityChanged(boolean isVisible) { - mCentralSurfaces.setBouncerShowingOverDream( - isVisible && mDreamOverlayStateController.isOverlayActive()); + mBouncerShowingOverDream = + isVisible && mDreamOverlayStateController.isOverlayActive(); if (!isVisible) { mCentralSurfaces.setPrimaryBouncerHiddenFraction(EXPANSION_HIDDEN); @@ -823,6 +824,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } @Override + public boolean isBouncerShowingOverDream() { + return mBouncerShowingOverDream; + } + + @Override public void setOccluded(boolean occluded, boolean animate) { final boolean wasOccluded = mKeyguardStateController.isOccluded(); final boolean isOccluding = !wasOccluded && occluded; diff --git a/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt new file mode 100644 index 000000000000..88c710aedf93 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt @@ -0,0 +1,120 @@ +/* + * 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.back.domain.interactor + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.shade.QuickSettingsController +import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.ShadeViewController +import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager +import com.android.systemui.util.mockito.whenever +import junit.framework.Assert.assertFalse +import junit.framework.Assert.assertTrue +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.anyBoolean +import org.mockito.Mockito.atLeastOnce +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.junit.MockitoJUnit + +@SmallTest +@RunWith(AndroidJUnit4::class) +class BackActionInteractorTest : SysuiTestCase() { + @JvmField @Rule var mockitoRule = MockitoJUnit.rule() + + @Mock private lateinit var statusBarStateController: StatusBarStateController + @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager + @Mock private lateinit var shadeController: ShadeController + @Mock private lateinit var qsController: QuickSettingsController + @Mock private lateinit var shadeViewController: ShadeViewController + + private lateinit var backActionInteractor: BackActionInteractor + + @Before + fun setup() { + backActionInteractor = + BackActionInteractor( + statusBarStateController, + statusBarKeyguardViewManager, + shadeController, + ) + backActionInteractor.setup(qsController, shadeViewController) + } + + @Test + fun testOnBackRequested_keyguardCanHandleBackPressed() { + whenever(statusBarKeyguardViewManager.canHandleBackPressed()).thenReturn(true) + + val result = backActionInteractor.onBackRequested() + + assertTrue(result) + verify(statusBarKeyguardViewManager, atLeastOnce()).onBackPressed() + } + + @Test + fun testOnBackRequested_quickSettingsIsCustomizing() { + whenever(qsController.isCustomizing).thenReturn(true) + + val result = backActionInteractor.onBackRequested() + + assertTrue(result) + verify(qsController, atLeastOnce()).closeQsCustomizer() + verify(statusBarKeyguardViewManager, never()).onBackPressed() + } + + @Test + fun testOnBackRequested_quickSettingsExpanded() { + whenever(qsController.expanded).thenReturn(true) + + val result = backActionInteractor.onBackRequested() + + assertTrue(result) + verify(shadeViewController, atLeastOnce()).animateCollapseQs(anyBoolean()) + verify(statusBarKeyguardViewManager, never()).onBackPressed() + } + + @Test + fun testOnBackRequested_closeUserSwitcherIfOpen() { + whenever(shadeViewController.closeUserSwitcherIfOpen()).thenReturn(true) + + val result = backActionInteractor.onBackRequested() + + assertTrue(result) + verify(statusBarKeyguardViewManager, never()).onBackPressed() + verify(shadeViewController, never()).animateCollapseQs(anyBoolean()) + } + + @Test + fun testOnBackRequested_returnsFalse() { + // make shouldBackBeHandled return false + whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) + + val result = backActionInteractor.onBackRequested() + + assertFalse(result) + verify(statusBarKeyguardViewManager, never()).onBackPressed() + verify(shadeViewController, never()).animateCollapseQs(anyBoolean()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index af40e5b04866..c737a18ea8a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -27,6 +27,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.back.domain.interactor.BackActionInteractor import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.dock.DockManager @@ -91,6 +92,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Mock private lateinit var view: NotificationShadeWindowView @Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController @Mock private lateinit var centralSurfaces: CentralSurfaces + @Mock private lateinit var backActionInteractor: BackActionInteractor @Mock private lateinit var dockManager: DockManager @Mock private lateinit var notificationPanelViewController: NotificationPanelViewController @Mock private lateinit var notificationShadeDepthController: NotificationShadeDepthController @@ -171,6 +173,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { statusBarWindowStateController, lockIconViewController, centralSurfaces, + backActionInteractor, notificationShadeWindowController, unfoldTransitionProgressProvider, keyguardUnlockAnimationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt index d3ecc3d52fbd..1740284a26dd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt @@ -27,6 +27,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.back.domain.interactor.BackActionInteractor import com.android.systemui.bouncer.data.factory.BouncerMessageFactory import com.android.systemui.bouncer.data.repository.FakeBouncerMessageRepository import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor @@ -93,6 +94,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() { @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController @Mock private lateinit var shadeController: ShadeController @Mock private lateinit var centralSurfaces: CentralSurfaces + @Mock private lateinit var backActionInteractor: BackActionInteractor @Mock private lateinit var dockManager: DockManager @Mock private lateinit var notificationPanelViewController: NotificationPanelViewController @Mock private lateinit var notificationStackScrollLayout: NotificationStackScrollLayout @@ -184,6 +186,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() { statusBarWindowStateController, lockIconViewController, centralSurfaces, + backActionInteractor, notificationShadeWindowController, unfoldTransitionProgressProvider, keyguardUnlockAnimationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 4762e57fa577..b9c0d1c89c66 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -98,6 +98,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.assist.AssistManager; +import com.android.systemui.back.domain.interactor.BackActionInteractor; import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -281,6 +282,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy; @Mock private LockscreenWallpaper mLockscreenWallpaper; @Mock private DozeServiceHost mDozeServiceHost; + @Mock private BackActionInteractor mBackActionInteractor; @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback; @Mock private VolumeComponent mVolumeComponent; @Mock private CommandQueue mCommandQueue; @@ -511,7 +513,9 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mBiometricUnlockControllerLazy, mAuthRippleController, mDozeServiceHost, - mPowerManager, mScreenPinningRequest, + mBackActionInteractor, + mPowerManager, + mScreenPinningRequest, mDozeScrimController, mVolumeComponent, mCommandQueue, @@ -825,9 +829,9 @@ public class CentralSurfacesImplTest extends SysuiTestCase { eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), mOnBackInvokedCallback.capture()); - when(mNotificationPanelViewController.canBeCollapsed()).thenReturn(true); + when(mBackActionInteractor.shouldBackBeHandled()).thenReturn(true); mOnBackInvokedCallback.getValue().onBackInvoked(); - verify(mShadeController).animateCollapseShade(); + verify(mBackActionInteractor).onBackRequested(); } /** @@ -845,6 +849,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { OnBackAnimationCallback onBackAnimationCallback = (OnBackAnimationCallback) (mOnBackInvokedCallback.getValue()); + when(mBackActionInteractor.shouldBackBeHandled()).thenReturn(true); when(mNotificationPanelViewController.canBeCollapsed()).thenReturn(true); BackEvent fakeSwipeInFromLeftEdge = new BackEvent(20.0f, 100.0f, 1.0f, BackEvent.EDGE_LEFT); @@ -867,6 +872,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { OnBackAnimationCallback onBackAnimationCallback = (OnBackAnimationCallback) (mOnBackInvokedCallback.getValue()); + when(mBackActionInteractor.shouldBackBeHandled()).thenReturn(true); when(mNotificationPanelViewController.canBeCollapsed()).thenReturn(true); BackEvent fakeSwipeInFromLeftEdge = new BackEvent(20.0f, 10.0f, 0.0f, BackEvent.EDGE_LEFT); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 914e29579c79..548e1b501d45 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -60,16 +60,16 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; -import com.android.systemui.dock.DockManager; -import com.android.systemui.dreams.DreamOverlayStateController; -import com.android.systemui.flags.FeatureFlags; -import com.android.systemui.flags.Flags; -import com.android.systemui.bouncer.ui.BouncerView; -import com.android.systemui.bouncer.ui.BouncerViewDelegate; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; +import com.android.systemui.bouncer.ui.BouncerView; +import com.android.systemui.bouncer.ui.BouncerViewDelegate; +import com.android.systemui.dock.DockManager; +import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.TaskbarDelegate; import com.android.systemui.plugins.ActivityStarter; @@ -647,21 +647,21 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { @Test public void testReportBouncerOnDreamWhenVisible() { mBouncerExpansionCallback.onVisibilityChanged(true); - verify(mCentralSurfaces).setBouncerShowingOverDream(false); + assertFalse(mStatusBarKeyguardViewManager.isBouncerShowingOverDream()); Mockito.clearInvocations(mCentralSurfaces); when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true); mBouncerExpansionCallback.onVisibilityChanged(true); - verify(mCentralSurfaces).setBouncerShowingOverDream(true); + assertTrue(mStatusBarKeyguardViewManager.isBouncerShowingOverDream()); } @Test public void testReportBouncerOnDreamWhenNotVisible() { mBouncerExpansionCallback.onVisibilityChanged(false); - verify(mCentralSurfaces).setBouncerShowingOverDream(false); + assertFalse(mStatusBarKeyguardViewManager.isBouncerShowingOverDream()); Mockito.clearInvocations(mCentralSurfaces); when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true); mBouncerExpansionCallback.onVisibilityChanged(false); - verify(mCentralSurfaces).setBouncerShowingOverDream(false); + assertFalse(mStatusBarKeyguardViewManager.isBouncerShowingOverDream()); } @Test |