diff options
9 files changed, 89 insertions, 62 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt index eceda8453902..6fde84a35fb1 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt @@ -17,38 +17,52 @@ package com.android.systemui.shade.domain.interactor import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.user.domain.interactor.UserInteractor import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn /** Business logic for shade interactions. */ @SysUISingleton class ShadeInteractor @Inject constructor( + @Application scope: CoroutineScope, disableFlagsRepository: DisableFlagsRepository, keyguardRepository: KeyguardRepository, userSetupRepository: UserSetupRepository, deviceProvisionedController: DeviceProvisionedController, userInteractor: UserInteractor, ) { + /** Emits true if the shade is currently allowed and false otherwise. */ + val isShadeEnabled: StateFlow<Boolean> = + disableFlagsRepository.disableFlags + .map { it.isShadeEnabled() } + .stateIn(scope, SharingStarted.Eagerly, initialValue = false) + /** Emits true if the shade can be expanded from QQS to QS and false otherwise. */ val isExpandToQsEnabled: Flow<Boolean> = combine( disableFlagsRepository.disableFlags, + isShadeEnabled, keyguardRepository.isDozing, userSetupRepository.isUserSetupFlow, - ) { disableFlags, isDozing, isUserSetup -> + ) { disableFlags, isShadeEnabled, isDozing, isUserSetup -> deviceProvisionedController.isDeviceProvisioned && // Disallow QS during setup if it's a simple user switcher. (The user intends to // use the lock screen user switcher, QS is not needed.) (isUserSetup || !userInteractor.isSimpleUserSwitcher) && - disableFlags.isShadeEnabled() && + isShadeEnabled && disableFlags.isQuickSettingsEnabled() && !isDozing } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index e2d2ac0fcb58..4710574ac20d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -32,6 +32,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.data.repository.ShadeRepository +import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView @@ -76,6 +77,7 @@ class LockscreenShadeTransitionController @Inject constructor( dumpManager: DumpManager, qsTransitionControllerFactory: LockscreenShadeQsTransitionController.Factory, private val shadeRepository: ShadeRepository, + private val shadeInteractor: ShadeInteractor, private val powerInteractor: PowerInteractor, ) : Dumpable { private var pulseHeight: Float = 0f @@ -558,7 +560,7 @@ class LockscreenShadeTransitionController @Inject constructor( animationHandler: ((Long) -> Unit)? = null, cancelAction: Runnable? = null ) { - if (centralSurfaces.isShadeDisabled) { + if (!shadeInteractor.isShadeEnabled.value) { cancelAction?.run() logger.logShadeDisabledOnGoToLockedShade() return 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 4ba09e175b8b..478baf2f58d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -203,8 +203,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { int getStatusBarHeight(); - boolean isShadeDisabled(); - boolean isLaunchingActivityOverLockscreen(); void onKeyguardViewManagerStatesUpdated(); @@ -380,14 +378,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { void resendMessage(Object msg); - int getDisabled1(); - - void setDisabled1(int disabled); - - int getDisabled2(); - - void setDisabled2(int disabled); - void setLastCameraLaunchSource(int source); void setLaunchCameraOnFinishedGoingToSleep(boolean launch); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index 332be2aa957d..6431ef958239 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -111,6 +111,9 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); + private int mDisabled1; + private int mDisabled2; + @Inject CentralSurfacesCommandQueueCallbacks( CentralSurfaces centralSurfaces, @@ -256,22 +259,14 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba return; } - int state2BeforeAdjustment = state2; - state2 = mRemoteInputQuickSettingsDisabler.adjustDisableFlags(state2); - Log.d(CentralSurfaces.TAG, - mDisableFlagsLogger.getDisableFlagsString( - /* new= */ new DisableFlagsLogger.DisableState( - state1, state2BeforeAdjustment), - /* newStateAfterLocalModification= */ new DisableFlagsLogger.DisableState( - state1, state2))); - - final int old1 = mCentralSurfaces.getDisabled1(); + final int old1 = mDisabled1; final int diff1 = state1 ^ old1; - mCentralSurfaces.setDisabled1(state1); + mDisabled1 = state1; - final int old2 = mCentralSurfaces.getDisabled2(); + state2 = mRemoteInputQuickSettingsDisabler.adjustDisableFlags(state2); + final int old2 = mDisabled2; final int diff2 = state2 ^ old2; - mCentralSurfaces.setDisabled2(state2); + mDisabled2 = state2; if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) { if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) { 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 77525d20b262..39b13d95345f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -362,26 +362,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } @Override - public int getDisabled1() { - return mDisabled1; - } - - @Override - public void setDisabled1(int disabled) { - mDisabled1 = disabled; - } - - @Override - public int getDisabled2() { - return mDisabled2; - } - - @Override - public void setDisabled2(int disabled) { - mDisabled2 = disabled; - } - - @Override public void setLastCameraLaunchSource(int source) { mLastCameraLaunchSource = source; } @@ -527,11 +507,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private CentralSurfacesComponent mCentralSurfacesComponent; - // Flags for disabling the status bar - // Two variables because the first one evidently ran out of room for new flags. - private int mDisabled1 = 0; - private int mDisabled2 = 0; - /** * This keeps track of whether we have (or haven't) registered the predictive back callback. * Since we can have visible -> visible transitions, we need to avoid @@ -1721,11 +1696,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { return mStatusBarWindowController.getStatusBarHeight(); } - @Override - public boolean isShadeDisabled() { - return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0; - } - private void updateReportRejectedTouchVisibility() { if (mReportRejectedTouch == null) { return; diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java index c72f4e77d4eb..a2c291281fdf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java @@ -169,6 +169,7 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true); mShadeInteractor = new ShadeInteractor( + mTestScope.getBackgroundScope(), mDisableFlagsRepository, mKeyguardRepository, new FakeUserSetupRepository(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt index 7392a94a04c2..45247977283a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt @@ -117,6 +117,7 @@ class ShadeInteractorTest : SysuiTestCase() { ) underTest = ShadeInteractor( + testScope.backgroundScope, disableFlagsRepository, keyguardRepository, userSetupRepository, @@ -126,6 +127,20 @@ class ShadeInteractorTest : SysuiTestCase() { } @Test + fun isShadeEnabled_matchesDisableFlagsRepo() = + testScope.runTest { + val actual by collectLastValue(underTest.isShadeEnabled) + + disableFlagsRepository.disableFlags.value = + DisableFlagsModel(disable2 = DISABLE2_NOTIFICATION_SHADE) + assertThat(actual).isFalse() + + disableFlagsRepository.disableFlags.value = DisableFlagsModel(disable2 = DISABLE2_NONE) + + assertThat(actual).isTrue() + } + + @Test fun isExpandToQsEnabled_deviceNotProvisioned_false() = testScope.runTest { whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(false) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 21e0f68cff2d..ff2f1065049b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -1,5 +1,6 @@ package com.android.systemui.statusbar +import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper @@ -11,6 +12,7 @@ import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager @@ -19,6 +21,9 @@ import com.android.systemui.power.data.repository.FakePowerRepository import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.data.repository.FakeShadeRepository +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel +import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.AmbientState @@ -28,8 +33,13 @@ import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.LSShadeTransitionLogger import com.android.systemui.statusbar.phone.ScrimController +import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository import com.android.systemui.statusbar.policy.FakeConfigurationController import com.android.systemui.util.mockito.mock +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent import org.junit.After import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -60,8 +70,11 @@ private fun <T> anyObject(): T { @SmallTest @RunWithLooper(setAsMainLooper = true) @RunWith(AndroidTestingRunner::class) +@OptIn(ExperimentalCoroutinesApi::class) class LockscreenShadeTransitionControllerTest : SysuiTestCase() { + private val testScope = TestScope(StandardTestDispatcher()) + lateinit var transitionController: LockscreenShadeTransitionController lateinit var row: ExpandableNotificationRow @Mock lateinit var statusbarStateController: SysuiStatusBarStateController @@ -87,6 +100,15 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController @Mock lateinit var activityStarter: ActivityStarter @Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback + private val disableFlagsRepository = FakeDisableFlagsRepository() + private val shadeInteractor = ShadeInteractor( + testScope.backgroundScope, + disableFlagsRepository, + keyguardRepository = FakeKeyguardRepository(), + userSetupRepository = FakeUserSetupRepository(), + deviceProvisionedController = mock(), + userInteractor = mock(), + ) private val powerInteractor = PowerInteractor( FakePowerRepository(), FalsingCollectorFake(), @@ -99,6 +121,10 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Before fun setup() { + // By default, have the shade enabled + disableFlagsRepository.disableFlags.value = DisableFlagsModel() + testScope.runCurrent() + val helper = NotificationTestHelper( mContext, mDependency, @@ -139,6 +165,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { qsTransitionControllerFactory = { qsTransitionController }, activityStarter = activityStarter, shadeRepository = FakeShadeRepository(), + shadeInteractor = shadeInteractor, powerInteractor = powerInteractor, ) transitionController.addCallback(transitionControllerCallback) @@ -214,7 +241,10 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Test fun testDontGoWhenShadeDisabled() { - whenever(mCentralSurfaces.isShadeDisabled).thenReturn(true) + disableFlagsRepository.disableFlags.value = DisableFlagsModel( + disable2 = DISABLE2_NOTIFICATION_SHADE, + ) + testScope.runCurrent() transitionController.goToLockedShade(null) verify(statusbarStateController, never()).setState(anyInt()) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java index 036b8becfbbc..8545b894ad41 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java @@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @@ -144,23 +145,32 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { @Test public void testDisableNotificationShade() { - when(mCentralSurfaces.getDisabled1()).thenReturn(StatusBarManager.DISABLE_NONE); - when(mCentralSurfaces.getDisabled2()).thenReturn(StatusBarManager.DISABLE_NONE); + // Start with nothing disabled + mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE, + StatusBarManager.DISABLE2_NONE, false); + when(mCommandQueue.panelsEnabled()).thenReturn(false); + // WHEN the new disable flags have the shade disabled mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false); + // THEN the shade is collapsed verify(mShadeController).animateCollapseShade(); } @Test public void testEnableNotificationShade() { - when(mCentralSurfaces.getDisabled1()).thenReturn(StatusBarManager.DISABLE_NONE); - when(mCentralSurfaces.getDisabled2()) - .thenReturn(StatusBarManager.DISABLE2_NOTIFICATION_SHADE); + // Start with the shade disabled + mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE, + StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false); + reset(mShadeController); + when(mCommandQueue.panelsEnabled()).thenReturn(true); + // WHEN the new disable flags have the shade enabled mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE, StatusBarManager.DISABLE2_NONE, false); + + // THEN the shade is not collapsed verify(mShadeController, never()).animateCollapseShade(); } |