diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 658f6a0878542..6988bd899e23c 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -209,7 +209,7 @@ public class LogModule { @SysUISingleton @CollapsedSbFragmentLog public static LogBuffer provideCollapsedSbFragmentLogBuffer(LogBufferFactory factory) { - return factory.create("CollapsedSbFragmentLog", 20); + return factory.create("CollapsedSbFragmentLog", 40); } /** 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 453dd1bb6f819..620d2824acfaa 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 @@ -14,11 +14,7 @@ package com.android.systemui.statusbar.phone.fragment; -import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS; -import static android.app.StatusBarManager.DISABLE_CLOCK; -import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS; -import static android.app.StatusBarManager.DISABLE_ONGOING_CALL_CHIP; -import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO; + import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE; import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT; @@ -112,8 +108,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private View mClockView; private View mOngoingCallChip; private View mNotificationIconAreaInner; - private int mDisabled1; - private int mDisabled2; + // Visibilities come in from external system callers via disable flags, but we also sometimes + // modify the visibilities internally. We need to store both so that we don't accidentally + // propagate our internally modified flags for too long. + private StatusBarVisibilityModel mLastSystemVisibility = + StatusBarVisibilityModel.createDefaultModel(); + private StatusBarVisibilityModel mLastModifiedVisibility = + StatusBarVisibilityModel.createDefaultModel(); private DarkIconManager mDarkIconManager; private final StatusBarFragmentComponent.Factory mStatusBarFragmentComponentFactory; private final CommandQueue mCommandQueue; @@ -141,7 +142,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; @@ -388,8 +389,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(/* animate= */ false); } /** @@ -408,49 +408,50 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue if (displayId != getContext().getDisplayId()) { return; } + mCollapsedStatusBarFragmentLogger + .logDisableFlagChange(new DisableState(state1, state2)); + mLastSystemVisibility = + StatusBarVisibilityModel.createModelFromFlags(state1, state2); + updateStatusBarVisibilities(animate); + } - int state1BeforeAdjustment = state1; - state1 = adjustDisableFlags(state1); + private void updateStatusBarVisibilities(boolean animate) { + StatusBarVisibilityModel previousModel = mLastModifiedVisibility; + StatusBarVisibilityModel newModel = calculateInternalModel(mLastSystemVisibility); + mCollapsedStatusBarFragmentLogger.logVisibilityModel(newModel); + mLastModifiedVisibility = newModel; - mCollapsedStatusBarFragmentLogger.logDisableFlagChange( - /* new= */ new DisableState(state1BeforeAdjustment, state2), - /* newAfterLocalModification= */ new DisableState(state1, state2)); - - final int old1 = mDisabled1; - final int diff1 = state1 ^ old1; - final int old2 = mDisabled2; - final int diff2 = state2 ^ old2; - mDisabled1 = state1; - mDisabled2 = 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); - hideOperatorName(animate); - } else { + if (newModel.getShowSystemInfo() != previousModel.getShowSystemInfo()) { + if (newModel.getShowSystemInfo()) { showEndSideContent(animate); showOperatorName(animate); + } else { + hideEndSideContent(animate); + hideOperatorName(animate); } } // The ongoing call chip and notification icon visibilities are intertwined, so update both // if either change. - if (((diff1 & DISABLE_ONGOING_CALL_CHIP) != 0) - || ((diff1 & DISABLE_NOTIFICATION_ICONS) != 0)) { - updateNotificationIconAreaAndCallChip(state1, animate); + if (newModel.getShowNotificationIcons() != previousModel.getShowNotificationIcons() + || newModel.getShowOngoingCallChip() != previousModel.getShowOngoingCallChip()) { + updateNotificationIconAreaAndCallChip(animate); } // The clock may have already been hidden, but we might want to shift its // visibility to GONE from INVISIBLE or vice versa - if ((diff1 & DISABLE_CLOCK) != 0 || mClockView.getVisibility() != clockHiddenMode()) { - if ((state1 & DISABLE_CLOCK) != 0) { - hideClock(animate); - } else { + if (newModel.getShowClock() != previousModel.getShowClock() + || mClockView.getVisibility() != clockHiddenMode()) { + if (newModel.getShowClock()) { showClock(animate); + } else { + hideClock(animate); } } } - protected int adjustDisableFlags(int state) { + private StatusBarVisibilityModel calculateInternalModel( + StatusBarVisibilityModel externalModel) { boolean headsUpVisible = mStatusBarFragmentComponent.getHeadsUpAppearanceController().shouldBeVisible(); @@ -459,34 +460,31 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue && shouldHideNotificationIcons() && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD && headsUpVisible)) { - state |= DISABLE_NOTIFICATION_ICONS; - state |= DISABLE_SYSTEM_INFO; - state |= DISABLE_CLOCK; + // Hide everything + return new StatusBarVisibilityModel( + /* showClock= */ false, + /* showNotificationIcons= */ false, + /* showOngoingCallChip= */ false, + /* showSystemInfo= */ false); } - if (mOngoingCallController.hasOngoingCall()) { - state &= ~DISABLE_ONGOING_CALL_CHIP; - } else { - state |= DISABLE_ONGOING_CALL_CHIP; - } - - if (headsUpVisible) { - // Disable everything on the left side of the status bar, since the app name for the - // heads up notification appears there instead. - state |= DISABLE_CLOCK; - state |= DISABLE_ONGOING_CALL_CHIP; - } - - return state; + boolean showClock = externalModel.getShowClock() && !headsUpVisible; + boolean showOngoingCallChip = mOngoingCallController.hasOngoingCall() && !headsUpVisible; + return new StatusBarVisibilityModel( + showClock, + externalModel.getShowNotificationIcons(), + showOngoingCallChip, + externalModel.getShowSystemInfo()); } /** * Updates the visibility of the notification icon area and ongoing call chip based on disabled1 * state. */ - private void updateNotificationIconAreaAndCallChip(int state1, boolean animate) { - boolean disableNotifications = (state1 & DISABLE_NOTIFICATION_ICONS) != 0; - boolean hasOngoingCall = (state1 & DISABLE_ONGOING_CALL_CHIP) == 0; + private void updateNotificationIconAreaAndCallChip(boolean animate) { + StatusBarVisibilityModel visibilityModel = mLastModifiedVisibility; + boolean disableNotifications = !visibilityModel.getShowNotificationIcons(); + boolean hasOngoingCall = visibilityModel.getShowOngoingCallChip(); // Hide notifications if the disable flag is set or we have an ongoing call. if (disableNotifications || hasOngoingCall) { @@ -683,7 +681,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 +696,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/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt index d64bc58a0c37c..59f74ec453a68 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt @@ -37,7 +37,6 @@ class CollapsedStatusBarFragmentLogger @Inject constructor( */ fun logDisableFlagChange( new: DisableFlagsLogger.DisableState, - newAfterLocalModification: DisableFlagsLogger.DisableState ) { buffer.log( TAG, @@ -45,19 +44,34 @@ class CollapsedStatusBarFragmentLogger @Inject constructor( { int1 = new.disable1 int2 = new.disable2 - long1 = newAfterLocalModification.disable1.toLong() - long2 = newAfterLocalModification.disable2.toLong() }, { disableFlagsLogger.getDisableFlagsString( old = null, new = DisableFlagsLogger.DisableState(int1, int2), - newAfterLocalModification = - DisableFlagsLogger.DisableState(long1.toInt(), long2.toInt()) ) } ) } + + fun logVisibilityModel(model: StatusBarVisibilityModel) { + buffer.log( + TAG, + LogLevel.INFO, + { + bool1 = model.showClock + bool2 = model.showNotificationIcons + bool3 = model.showOngoingCallChip + bool4 = model.showSystemInfo + }, + { "New visibilities calculated internally. " + + "showClock=$bool1 " + + "showNotificationIcons=$bool2 " + + "showOngoingCallChip=$bool3 " + + "showSystemInfo=$bool4" + } + ) + } } private const val TAG = "CollapsedSbFragment" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt new file mode 100644 index 0000000000000..cf54cb7aa9549 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt @@ -0,0 +1,58 @@ +/* + * 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.statusbar.phone.fragment + +import android.app.StatusBarManager.DISABLE2_NONE +import android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS +import android.app.StatusBarManager.DISABLE_CLOCK +import android.app.StatusBarManager.DISABLE_NONE +import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS +import android.app.StatusBarManager.DISABLE_ONGOING_CALL_CHIP +import android.app.StatusBarManager.DISABLE_SYSTEM_INFO + +/** A model for which parts of the status bar should be visible or not visible. */ +data class StatusBarVisibilityModel( + val showClock: Boolean, + val showNotificationIcons: Boolean, + val showOngoingCallChip: Boolean, + val showSystemInfo: Boolean, +) { + companion object { + /** Creates the default model. */ + @JvmStatic + fun createDefaultModel(): StatusBarVisibilityModel { + return createModelFromFlags(DISABLE_NONE, DISABLE2_NONE) + } + + /** + * Given a set of disabled flags, converts them into the correct visibility statuses. + * + * See [CommandQueue.Callbacks.disable]. + */ + @JvmStatic + fun createModelFromFlags(disabled1: Int, disabled2: Int): StatusBarVisibilityModel { + return StatusBarVisibilityModel( + showClock = (disabled1 and DISABLE_CLOCK) == 0, + showNotificationIcons = (disabled1 and DISABLE_NOTIFICATION_ICONS) == 0, + // TODO(b/279899176): [CollapsedStatusBarFragment] always overwrites this with the + // value of [OngoingCallController]. Do we need to process the flag here? + showOngoingCallChip = (disabled1 and DISABLE_ONGOING_CALL_CHIP) == 0, + showSystemInfo = + (disabled1 and DISABLE_SYSTEM_INFO) == 0 && + (disabled2 and DISABLE2_SYSTEM_ICONS) == 0 + ) + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt index 3a0a94ddd5112..ac3b28c72fa28 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt @@ -43,15 +43,39 @@ class CollapsedStatusBarFragmentLoggerTest : SysuiTestCase() { fun logDisableFlagChange_bufferHasStates() { val state = DisableFlagsLogger.DisableState(0, 1) - logger.logDisableFlagChange(state, state) + logger.logDisableFlagChange(state) val stringWriter = StringWriter() buffer.dump(PrintWriter(stringWriter), tailLength = 0) val actualString = stringWriter.toString() - val expectedLogString = disableFlagsLogger.getDisableFlagsString( - old = null, new = state, newAfterLocalModification = state - ) + val expectedLogString = + disableFlagsLogger.getDisableFlagsString( + old = null, + new = state, + newAfterLocalModification = null, + ) assertThat(actualString).contains(expectedLogString) } + + @Test + fun logVisibilityModel_bufferCorrect() { + logger.logVisibilityModel( + StatusBarVisibilityModel( + showClock = false, + showNotificationIcons = true, + showOngoingCallChip = false, + showSystemInfo = true, + ) + ) + + val stringWriter = StringWriter() + buffer.dump(PrintWriter(stringWriter), tailLength = 0) + val actualString = stringWriter.toString() + + assertThat(actualString).contains("showClock=false") + assertThat(actualString).contains("showNotificationIcons=true") + assertThat(actualString).contains("showOngoingCallChip=false") + assertThat(actualString).contains("showSystemInfo=true") + } } 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 2a3c775eaf544..03fafcb853251 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; @@ -173,6 +176,10 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { fragment.disable(DEFAULT_DISPLAY, 0, 0, false); assertEquals(View.VISIBLE, getEndSideContentView().getVisibility()); + + fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false); + + assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility()); } @Test @@ -278,6 +285,10 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { fragment.disable(DEFAULT_DISPLAY, 0, 0, false); Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE)); + + fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NOTIFICATION_ICONS, 0, false); + + Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.INVISIBLE)); } @Test @@ -291,6 +302,70 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { fragment.disable(DEFAULT_DISPLAY, 0, 0, false); assertEquals(View.VISIBLE, getClockView().getVisibility()); + + fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_CLOCK, 0, false); + + assertEquals(View.GONE, 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 @@ -323,7 +398,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.ongoing_call_chip).getVisibility()); Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.INVISIBLE)); - } @Test @@ -356,20 +430,26 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { public void disable_ongoingCallEnded_chipHidden() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); - when(mOngoingCallController.hasOngoingCall()).thenReturn(true); - // Ongoing call started + when(mOngoingCallController.hasOngoingCall()).thenReturn(true); fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.ongoing_call_chip).getVisibility()); // Ongoing call ended when(mOngoingCallController.hasOngoingCall()).thenReturn(false); - fragment.disable(DEFAULT_DISPLAY, 0, 0, false); assertEquals(View.GONE, mFragment.getView().findViewById(R.id.ongoing_call_chip).getVisibility()); + + // Ongoing call started + when(mOngoingCallController.hasOngoingCall()).thenReturn(true); + fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + + assertEquals(View.VISIBLE, + mFragment.getView().findViewById(R.id.ongoing_call_chip).getVisibility()); } @Test @@ -494,6 +574,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 +583,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { mAnimationScheduler, mLocationPublisher, mMockNotificationAreaController, - new ShadeExpansionStateManager(), + mShadeExpansionStateManager, mock(FeatureFlags.class), mStatusBarIconController, mIconManagerFactory, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt new file mode 100644 index 0000000000000..8e789cb2cae65 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt @@ -0,0 +1,108 @@ +/* + * 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.statusbar.phone.fragment + +import android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS +import android.app.StatusBarManager.DISABLE_CLOCK +import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS +import android.app.StatusBarManager.DISABLE_ONGOING_CALL_CHIP +import android.app.StatusBarManager.DISABLE_SYSTEM_INFO +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.Companion.createDefaultModel +import com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.Companion.createModelFromFlags +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +@SmallTest +class StatusBarVisibilityModelTest : SysuiTestCase() { + @Test + fun createDefaultModel_everythingEnabled() { + val result = createDefaultModel() + + val expected = + StatusBarVisibilityModel( + showClock = true, + showNotificationIcons = true, + showOngoingCallChip = true, + showSystemInfo = true, + ) + + assertThat(result).isEqualTo(expected) + } + + @Test + fun createModelFromFlags_clockNotDisabled_showClockTrue() { + val result = createModelFromFlags(disabled1 = 0, disabled2 = 0) + + assertThat(result.showClock).isTrue() + } + + @Test + fun createModelFromFlags_clockDisabled_showClockFalse() { + val result = createModelFromFlags(disabled1 = DISABLE_CLOCK, disabled2 = 0) + + assertThat(result.showClock).isFalse() + } + + @Test + fun createModelFromFlags_notificationIconsNotDisabled_showNotificationIconsTrue() { + val result = createModelFromFlags(disabled1 = 0, disabled2 = 0) + + assertThat(result.showNotificationIcons).isTrue() + } + + @Test + fun createModelFromFlags_notificationIconsDisabled_showNotificationIconsFalse() { + val result = createModelFromFlags(disabled1 = DISABLE_NOTIFICATION_ICONS, disabled2 = 0) + + assertThat(result.showNotificationIcons).isFalse() + } + + @Test + fun createModelFromFlags_ongoingCallChipNotDisabled_showOngoingCallChipTrue() { + val result = createModelFromFlags(disabled1 = 0, disabled2 = 0) + + assertThat(result.showOngoingCallChip).isTrue() + } + + @Test + fun createModelFromFlags_ongoingCallChipDisabled_showOngoingCallChipFalse() { + val result = createModelFromFlags(disabled1 = DISABLE_ONGOING_CALL_CHIP, disabled2 = 0) + + assertThat(result.showOngoingCallChip).isFalse() + } + + @Test + fun createModelFromFlags_systemInfoAndIconsNotDisabled_showSystemInfoTrue() { + val result = createModelFromFlags(disabled1 = 0, disabled2 = 0) + + assertThat(result.showSystemInfo).isTrue() + } + + @Test + fun createModelFromFlags_disable1SystemInfoDisabled_showSystemInfoFalse() { + val result = createModelFromFlags(disabled1 = DISABLE_SYSTEM_INFO, disabled2 = 0) + + assertThat(result.showSystemInfo).isFalse() + } + + @Test + fun createModelFromFlags_disable2SystemIconsDisabled_showSystemInfoFalse() { + val result = createModelFromFlags(disabled1 = 0, disabled2 = DISABLE2_SYSTEM_ICONS) + + assertThat(result.showSystemInfo).isFalse() + } +}