diff options
2 files changed, 90 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index 453dd1bb6f81..9c3c53e7ed96 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -112,8 +112,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private View mClockView; private View mOngoingCallChip; private View mNotificationIconAreaInner; - private int mDisabled1; - private int mDisabled2; + // Disabled flags come in from external callers, but we also sometimes modify them internally. + // We need to store both so that we don't accidentally propagate our internally modified flags + // for too long. + private int mExternalDisabled1; + private int mExternalDisabled2; + private int mInternalDisabled1; + private int mInternalDisabled2; private DarkIconManager mDarkIconManager; private final StatusBarFragmentComponent.Factory mStatusBarFragmentComponentFactory; private final CommandQueue mCommandQueue; @@ -141,7 +146,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private final OngoingCallListener mOngoingCallListener = new OngoingCallListener() { @Override public void onOngoingCallStateChanged(boolean animate) { - disable(getContext().getDisplayId(), mDisabled1, mDisabled2, animate); + updateStatusBarVisibilities(animate); } }; private OperatorNameViewController mOperatorNameViewController; @@ -389,7 +394,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue notificationIconArea.addView(mNotificationIconAreaInner); // #disable should have already been called, so use the disable values to set visibility. - updateNotificationIconAreaAndCallChip(mDisabled1, false); + updateNotificationIconAreaAndCallChip(mInternalDisabled1, false); } /** @@ -403,12 +408,21 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue return mStatusBarFragmentComponent; } + private void updateStatusBarVisibilities(boolean animate) { + // Make sure that we pass the last *external* flags so that we don't accidentally propagate + // our internal adjustments. + disable(getContext().getDisplayId(), mExternalDisabled1, mExternalDisabled2, animate); + } + @Override public void disable(int displayId, int state1, int state2, boolean animate) { if (displayId != getContext().getDisplayId()) { return; } + mExternalDisabled1 = state1; + mExternalDisabled2 = state2; + int state1BeforeAdjustment = state1; state1 = adjustDisableFlags(state1); @@ -416,12 +430,12 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue /* new= */ new DisableState(state1BeforeAdjustment, state2), /* newAfterLocalModification= */ new DisableState(state1, state2)); - final int old1 = mDisabled1; + final int old1 = mInternalDisabled1; final int diff1 = state1 ^ old1; - final int old2 = mDisabled2; + final int old2 = mInternalDisabled2; final int diff2 = state2 ^ old2; - mDisabled1 = state1; - mDisabled2 = state2; + mInternalDisabled1 = state1; + mInternalDisabled2 = state2; if ((diff1 & DISABLE_SYSTEM_INFO) != 0 || ((diff2 & DISABLE2_SYSTEM_ICONS) != 0)) { if ((state1 & DISABLE_SYSTEM_INFO) != 0 || ((state2 & DISABLE2_SYSTEM_ICONS) != 0)) { hideEndSideContent(animate); @@ -683,7 +697,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue @Override public void onDozingChanged(boolean isDozing) { - disable(getContext().getDisplayId(), mDisabled1, mDisabled2, false /* animate */); + updateStatusBarVisibilities(/* animate= */ false); } @Nullable @@ -698,10 +712,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue return mSystemEventAnimator.onSystemEventAnimationFinish(hasPersistentDot); } - private boolean isSystemIconAreaDisabled() { - return (mDisabled1 & DISABLE_SYSTEM_INFO) != 0 || (mDisabled2 & DISABLE2_SYSTEM_ICONS) != 0; - } - private void updateStatusBarLocation(int left, int right) { int leftMargin = left - mStatusBar.getLeft(); int rightMargin = mStatusBar.getRight() - right; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java index 2a3c775eaf54..209dc5ad48d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone.fragment; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED; +import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_OPEN; import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN; import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT; import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE; @@ -93,6 +95,7 @@ import java.util.List; public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { private NotificationIconAreaController mMockNotificationAreaController; + private ShadeExpansionStateManager mShadeExpansionStateManager; private View mNotificationAreaInner; private OngoingCallController mOngoingCallController; private SystemStatusAnimationScheduler mAnimationScheduler; @@ -293,6 +296,67 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { assertEquals(View.VISIBLE, getClockView().getVisibility()); } + + @Test + public void disable_shadeOpenAndShouldHide_everythingHidden() { + CollapsedStatusBarFragment fragment = resumeAndGetFragment(); + + // WHEN the shade is open and configured to hide the status bar icons + mShadeExpansionStateManager.updateState(STATE_OPEN); + when(mShadeViewController.shouldHideStatusBarIconsWhenExpanded()).thenReturn(true); + + fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + + // THEN all views are hidden + assertEquals(View.INVISIBLE, getClockView().getVisibility()); + Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.INVISIBLE)); + assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility()); + } + + @Test + public void disable_shadeOpenButNotShouldHide_everythingShown() { + CollapsedStatusBarFragment fragment = resumeAndGetFragment(); + + // WHEN the shade is open but *not* configured to hide the status bar icons + mShadeExpansionStateManager.updateState(STATE_OPEN); + when(mShadeViewController.shouldHideStatusBarIconsWhenExpanded()).thenReturn(false); + + fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + + // THEN all views are shown + assertEquals(View.VISIBLE, getClockView().getVisibility()); + Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE)); + assertEquals(View.VISIBLE, getEndSideContentView().getVisibility()); + } + + /** Regression test for b/279790651. */ + @Test + public void disable_shadeOpenAndShouldHide_thenShadeNotOpenAndDozingUpdate_everythingShown() { + CollapsedStatusBarFragment fragment = resumeAndGetFragment(); + + // WHEN the shade is open and configured to hide the status bar icons + mShadeExpansionStateManager.updateState(STATE_OPEN); + when(mShadeViewController.shouldHideStatusBarIconsWhenExpanded()).thenReturn(true); + + fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + + // THEN all views are hidden + assertEquals(View.INVISIBLE, getClockView().getVisibility()); + Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.INVISIBLE)); + assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility()); + + // WHEN the shade is updated to no longer be open + mShadeExpansionStateManager.updateState(STATE_CLOSED); + + // AND we internally request an update via dozing change + fragment.onDozingChanged(true); + + // THEN all views are shown + assertEquals(View.VISIBLE, getClockView().getVisibility()); + Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE)); + assertEquals(View.VISIBLE, getEndSideContentView().getVisibility()); + } + @Test public void userChip_defaultVisibilityIsGone() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); @@ -494,6 +558,8 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager); mSecureSettings = mock(SecureSettings.class); + mShadeExpansionStateManager = new ShadeExpansionStateManager(); + setUpNotificationIconAreaController(); return new CollapsedStatusBarFragment( mStatusBarFragmentComponentFactory, @@ -501,7 +567,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { mAnimationScheduler, mLocationPublisher, mMockNotificationAreaController, - new ShadeExpansionStateManager(), + mShadeExpansionStateManager, mock(FeatureFlags.class), mStatusBarIconController, mIconManagerFactory, |