diff options
6 files changed, 108 insertions, 36 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 9a6e5e21d900..1b1387ead630 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -40,6 +40,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; +import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED; import static com.android.systemui.statusbar.VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES; import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD; import static com.android.systemui.util.DumpUtilsKt.asIndenting; @@ -5031,10 +5032,37 @@ public final class NotificationPanelViewController implements Dumpable { return mExpandedFraction; } + /** + * This method should not be used anymore, you should probably use {@link #isShadeFullyOpen()} + * instead. It was overused as indicating if shade is open or we're on keyguard/AOD. + * Moving forward we should be explicit about the what state we're checking. + * @return if panel is covering the screen, which means we're in expanded shade or keyguard/AOD + * + * @deprecated depends on the state you check, use {@link #isShadeFullyOpen()}, + * {@link #isOnAod()}, {@link #isOnKeyguard()} instead. + */ + @Deprecated public boolean isFullyExpanded() { return mExpandedHeight >= getMaxPanelTransitionDistance(); } + /** + * Returns true if shade is fully opened, that is we're actually in the notification shade + * with QQS or QS. It's different from {@link #isFullyExpanded()} that it will not report + * shade as always expanded if we're on keyguard/AOD. It will return true only when user goes + * from keyguard to shade. + */ + public boolean isShadeFullyOpen() { + if (mBarState == SHADE) { + return isFullyExpanded(); + } else if (mBarState == SHADE_LOCKED) { + return true; + } else { + // case of two finger swipe from the top of keyguard + return computeQsExpansionFraction() == 1; + } + } + public boolean isFullyCollapsed() { return mExpandedFraction <= 0.0f; } diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java index a41a15d4e2a2..ad5a68e4dc3f 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java @@ -63,8 +63,14 @@ public interface ShadeController { */ boolean closeShadeIfOpen(); - /** Returns whether the shade is currently open or opening. */ - boolean isShadeOpen(); + /** + * Returns whether the shade is currently open. + * Even though in the current implementation shade is in expanded state on keyguard, this + * method makes distinction between shade being truly open and plain keyguard state: + * - if QS and notifications are visible on the screen, return true + * - for any other state, including keyguard, return false + */ + boolean isShadeFullyOpen(); /** * Add a runnable for NotificationPanelView to post when the panel is expanded. diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java index 638e74883f23..026673adb86b 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java @@ -154,9 +154,8 @@ public final class ShadeControllerImpl implements ShadeController { } @Override - public boolean isShadeOpen() { - return mNotificationPanelViewController.isExpanding() - || mNotificationPanelViewController.isFullyExpanded(); + public boolean isShadeFullyOpen() { + return mNotificationPanelViewController.isShadeFullyOpen(); } @Override 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 00a9916f5ac1..b2d48bb1d84c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -34,6 +34,7 @@ import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF; +import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; @@ -1121,10 +1122,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private void onFoldedStateChangedInternal(boolean isFolded, boolean willGoToSleep) { // Folded state changes are followed by a screen off event. // By default turning off the screen also closes the shade. - // We want to make sure that the shade status is kept after - // folding/unfolding. - boolean isShadeOpen = mShadeController.isShadeOpen(); - boolean leaveOpen = isShadeOpen && !willGoToSleep; + // We want to make sure that the shade status is kept after folding/unfolding. + boolean isShadeOpen = mShadeController.isShadeFullyOpen(); + boolean leaveOpen = isShadeOpen && !willGoToSleep && mState == SHADE; if (DEBUG) { Log.d(TAG, String.format( "#onFoldedStateChanged(): " @@ -1135,18 +1135,17 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { isFolded, willGoToSleep, isShadeOpen, leaveOpen)); } if (leaveOpen) { - if (mKeyguardStateController.isShowing()) { - // When device state changes on keyguard we don't want to keep the state of - // the shade and instead we open clean state of keyguard with shade closed. - // Normally some parts of QS state (like expanded/collapsed) are persisted and - // that causes incorrect UI rendering, especially when changing state with QS - // expanded. To prevent that we can close QS which resets QS and some parts of - // the shade to its default state. Read more in b/201537421 - mCloseQsBeforeScreenOff = true; - } else { - // below makes shade stay open when going from folded to unfolded - mStatusBarStateController.setLeaveOpenOnKeyguardHide(true); - } + // below makes shade stay open when going from folded to unfolded + mStatusBarStateController.setLeaveOpenOnKeyguardHide(true); + } + if (mState != SHADE && isShadeOpen) { + // When device state changes on KEYGUARD/SHADE_LOCKED we don't want to keep the state of + // the shade and instead we open clean state of keyguard with shade closed. + // Normally some parts of QS state (like expanded/collapsed) are persisted and + // that causes incorrect UI rendering, especially when changing state with QS + // expanded. To prevent that we can close QS which resets QS and some parts of + // the shade to its default state. Read more in b/201537421 + mCloseQsBeforeScreenOff = true; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index f7358899ace3..9e038c4c905f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -1709,6 +1709,42 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { assertThat(mNotificationPanelViewController.isFullyExpanded()).isTrue(); } + @Test + public void shadeExpanded_inShadeState() { + mStatusBarStateController.setState(SHADE); + + mNotificationPanelViewController.setExpandedHeight(0); + assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse(); + + int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance(); + mNotificationPanelViewController.setExpandedHeight(transitionDistance); + assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue(); + } + + @Test + public void shadeExpanded_onKeyguard() { + mStatusBarStateController.setState(KEYGUARD); + + int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance(); + mNotificationPanelViewController.setExpandedHeight(transitionDistance); + assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse(); + + // set maxQsExpansion in NPVC + int maxQsExpansion = 123; + mNotificationPanelViewController.setQs(mQs); + when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion); + triggerLayoutChange(); + + mNotificationPanelViewController.setQsExpansionHeight(maxQsExpansion); + assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue(); + } + + @Test + public void shadeExpanded_onShadeLocked() { + mStatusBarStateController.setState(SHADE_LOCKED); + assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue(); + } + private static MotionEvent createMotionEvent(int x, int y, int action) { return MotionEvent.obtain( /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0); 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 ed84e4268c90..7be31d89915d 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 @@ -19,6 +19,9 @@ package com.android.systemui.statusbar.phone; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; +import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; +import static com.android.systemui.statusbar.StatusBarState.SHADE; + import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; @@ -828,7 +831,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true); when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5); when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(true); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); try { mCentralSurfaces.handleVisibleToUserChanged(true); @@ -847,7 +850,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5); when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(false); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); try { mCentralSurfaces.handleVisibleToUserChanged(true); @@ -988,7 +991,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { public void testShowKeyguardImplementation_setsState() { when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(new SparseArray<>()); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); // By default, showKeyguardImpl sets state to KEYGUARD. mCentralSurfaces.showKeyguardImpl(); @@ -1045,7 +1048,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { public void collapseShade_callsanimateCollapseShade_whenExpanded() { // GIVEN the shade is expanded mCentralSurfaces.onShadeExpansionFullyChanged(true); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); // WHEN collapseShade is called mCentralSurfaces.collapseShade(); @@ -1058,7 +1061,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { public void collapseShade_doesNotCallanimateCollapseShade_whenCollapsed() { // GIVEN the shade is collapsed mCentralSurfaces.onShadeExpansionFullyChanged(false); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); // WHEN collapseShade is called mCentralSurfaces.collapseShade(); @@ -1071,7 +1074,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { public void collapseShadeForBugReport_callsanimateCollapseShade_whenFlagDisabled() { // GIVEN the shade is expanded & flag enabled mCentralSurfaces.onShadeExpansionFullyChanged(true); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); mFeatureFlags.set(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, false); // WHEN collapseShadeForBugreport is called @@ -1085,7 +1088,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { public void collapseShadeForBugReport_doesNotCallanimateCollapseShade_whenFlagEnabled() { // GIVEN the shade is expanded & flag enabled mCentralSurfaces.onShadeExpansionFullyChanged(true); - mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE); + mCentralSurfaces.setBarStateForTest(SHADE); mFeatureFlags.set(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, true); // WHEN collapseShadeForBugreport is called @@ -1097,10 +1100,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Test public void deviceStateChange_unfolded_shadeOpen_setsLeaveOpenOnKeyguardHide() { - when(mKeyguardStateController.isShowing()).thenReturn(false); setFoldedStates(FOLD_STATE_FOLDED); setGoToSleepStates(FOLD_STATE_FOLDED); - when(mNotificationPanelViewController.isFullyExpanded()).thenReturn(true); + mCentralSurfaces.setBarStateForTest(SHADE); + when(mNotificationPanelViewController.isShadeFullyOpen()).thenReturn(true); setDeviceState(FOLD_STATE_UNFOLDED); @@ -1109,10 +1112,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Test public void deviceStateChange_unfolded_shadeOpen_onKeyguard_doesNotSetLeaveOpenOnKeyguardHide() { - when(mKeyguardStateController.isShowing()).thenReturn(true); setFoldedStates(FOLD_STATE_FOLDED); setGoToSleepStates(FOLD_STATE_FOLDED); - when(mNotificationPanelViewController.isFullyExpanded()).thenReturn(true); + mCentralSurfaces.setBarStateForTest(KEYGUARD); + when(mNotificationPanelViewController.isShadeFullyOpen()).thenReturn(true); setDeviceState(FOLD_STATE_UNFOLDED); @@ -1124,7 +1127,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase { public void deviceStateChange_unfolded_shadeClose_doesNotSetLeaveOpenOnKeyguardHide() { setFoldedStates(FOLD_STATE_FOLDED); setGoToSleepStates(FOLD_STATE_FOLDED); - when(mNotificationPanelViewController.isFullyExpanded()).thenReturn(false); + mCentralSurfaces.setBarStateForTest(SHADE); + when(mNotificationPanelViewController.isShadeFullyOpen()).thenReturn(false); setDeviceState(FOLD_STATE_UNFOLDED); @@ -1158,12 +1162,12 @@ public class CentralSurfacesImplTest extends SysuiTestCase { // it to remain visible. when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true); setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */); - verify(mStatusBarStateController, never()).setState(StatusBarState.SHADE); + verify(mStatusBarStateController, never()).setState(SHADE); // Once the animation ends, verify that the keyguard is actually hidden. when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false); setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */); - verify(mStatusBarStateController).setState(StatusBarState.SHADE); + verify(mStatusBarStateController).setState(SHADE); } @Test @@ -1176,7 +1180,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { // immediately hide the keyguard. when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false); setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */); - verify(mStatusBarStateController).setState(StatusBarState.SHADE); + verify(mStatusBarStateController).setState(SHADE); } /** |