diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml new file mode 100644 index 0000000000000..f0b59d825417d --- /dev/null +++ b/packages/SystemUI/res/layout/combined_qs_header.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 702a3549cbba7..b4c9a93959838 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -79,7 +79,11 @@ android:clipToPadding="false" android:clipChildren="false"> - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/xml/qs_header.xml b/packages/SystemUI/res/xml/qs_header.xml new file mode 100644 index 0000000000000..72e518eab839d --- /dev/null +++ b/packages/SystemUI/res/xml/qs_header.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/xml/split_header.xml b/packages/SystemUI/res/xml/split_header.xml new file mode 100644 index 0000000000000..a3ee1e2fae645 --- /dev/null +++ b/packages/SystemUI/res/xml/split_header.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.java index 3d44304f010ec..77e907c2e8614 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.java @@ -187,6 +187,13 @@ public class FeatureFlags { return isEnabled(Flags.NEW_USER_SWITCHER); } + /** + * Use the new single view QS headers + */ + public boolean useCombinedQSHeaders() { + return isEnabled(Flags.COMBINED_QS_HEADERS); + } + /** static method for the system setting */ public static boolean isProviderModelSettingEnabled(Context context) { return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL); diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java index 3761d42ae98c7..f09c797a6608e 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java @@ -77,21 +77,24 @@ public class Flags { public static final BooleanFlag NEW_USER_SWITCHER = new BooleanFlag(500, true); + public static final BooleanFlag COMBINED_QS_HEADERS = + new BooleanFlag(501, false); + /***************************************/ // 600- status bar public static final BooleanFlag COMBINED_STATUS_BAR_SIGNAL_ICONS = - new BooleanFlag(501, false); + new BooleanFlag(601, false); /***************************************/ // 700 - dialer/calls public static final BooleanFlag ONGOING_CALL_STATUS_BAR_CHIP = - new BooleanFlag(600, true); + new BooleanFlag(700, true); public static final BooleanFlag ONGOING_CALL_IN_IMMERSIVE = - new BooleanFlag(601, true); + new BooleanFlag(701, true); public static final BooleanFlag ONGOING_CALL_IN_IMMERSIVE_CHIP_TAP = - new BooleanFlag(602, true); + new BooleanFlag(702, true); // Pay no attention to the reflection behind the curtain. // ========================== Curtain ========================== diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 98149f407eb20..1343bdbf7be55 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -103,6 +103,8 @@ public class QuickStatusBarHeader extends FrameLayout { private boolean mHasCenterCutout; private boolean mConfigShowBatteryEstimate; + private boolean mUseCombinedQSHeader; + public QuickStatusBarHeader(Context context, AttributeSet attrs) { super(context, attrs); } @@ -160,7 +162,9 @@ public class QuickStatusBarHeader extends FrameLayout { void onAttach(TintedIconManager iconManager, QSExpansionPathInterpolator qsExpansionPathInterpolator, List rssiIgnoredSlots, - StatusBarContentInsetsProvider insetsProvider) { + StatusBarContentInsetsProvider insetsProvider, + boolean useCombinedQSHeader) { + mUseCombinedQSHeader = useCombinedQSHeader; mTintedIconManager = iconManager; mRssiIgnoredSlots = rssiIgnoredSlots; mInsetsProvider = insetsProvider; @@ -236,8 +240,11 @@ public class QuickStatusBarHeader extends FrameLayout { // status bar is already displayed out of QS in split shade boolean shouldUseSplitShade = resources.getBoolean(R.bool.config_use_split_notification_shade); - mStatusIconsView.setVisibility(shouldUseSplitShade ? View.GONE : View.VISIBLE); - mDatePrivacyView.setVisibility(shouldUseSplitShade ? View.GONE : View.VISIBLE); + + mStatusIconsView.setVisibility( + shouldUseSplitShade || mUseCombinedQSHeader ? View.GONE : View.VISIBLE); + mDatePrivacyView.setVisibility( + shouldUseSplitShade || mUseCombinedQSHeader ? View.GONE : View.VISIBLE); mConfigShowBatteryEstimate = resources.getBoolean(R.bool.config_showBatteryEstimateQSBH); @@ -276,8 +283,8 @@ public class QuickStatusBarHeader extends FrameLayout { } MarginLayoutParams qqsLP = (MarginLayoutParams) mHeaderQsPanel.getLayoutParams(); - qqsLP.topMargin = mContext.getResources() - .getDimensionPixelSize(R.dimen.qqs_layout_margin_top); + qqsLP.topMargin = shouldUseSplitShade || !mUseCombinedQSHeader ? mContext.getResources() + .getDimensionPixelSize(R.dimen.qqs_layout_margin_top) : qsOffsetHeight; mHeaderQsPanel.setLayoutParams(qqsLP); updateBatteryMode(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java index 9e2b7306ab8ca..6a57e45d64f6d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java @@ -229,8 +229,8 @@ class QuickStatusBarHeaderController extends ViewController>() - verify(view).onAttach(any(), any(), capture(captor), any()) + verify(view).onAttach(any(), any(), capture(captor), any(), anyBoolean()) assertThat(captor.value).containsExactly( mContext.getString(com.android.internal.R.string.status_bar_mobile) @@ -264,7 +265,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() { controller.init() val captor = argumentCaptor>() - verify(view).onAttach(any(), any(), capture(captor), any()) + verify(view).onAttach(any(), any(), capture(captor), any(), anyBoolean()) assertThat(captor.value).containsExactly( mContext.getString(com.android.internal.R.string.status_bar_no_calling), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt index a9e8164e8b873..4f68a3d0ad284 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt @@ -1,8 +1,7 @@ package com.android.systemui.statusbar.phone -import android.content.Context -import android.content.res.Resources import android.test.suitebuilder.annotation.SmallTest +import android.testing.AndroidTestingRunner import android.view.View import com.android.systemui.R import com.android.systemui.SysuiTestCase @@ -15,14 +14,16 @@ import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock -import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit +import org.mockito.Mockito.`when` as whenever @SmallTest +@RunWith(AndroidTestingRunner::class) class SplitShadeHeaderControllerTest : SysuiTestCase() { @Mock private lateinit var view: View @@ -33,8 +34,6 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() { @Mock private lateinit var featureFlags: FeatureFlags @Mock private lateinit var batteryMeterView: BatteryMeterView @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController - @Mock private lateinit var resources: Resources - @Mock private lateinit var context: Context @JvmField @Rule val mockitoRule = MockitoJUnit.rule() var viewVisibility = View.GONE @@ -45,8 +44,8 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() { whenever(view.findViewById(R.id.batteryRemainingIcon)) .thenReturn(batteryMeterView) whenever(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons) + whenever(view.context).thenReturn(context) whenever(statusIcons.context).thenReturn(context) - whenever(context.resources).thenReturn(resources) whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any())) .thenReturn(qsCarrierGroupControllerBuilder) whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController) @@ -55,6 +54,7 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() { null } whenever(view.visibility).thenAnswer { _ -> viewVisibility } + whenever(featureFlags.useCombinedQSHeaders()).thenReturn(false) splitShadeHeaderController = SplitShadeHeaderController(view, statusBarIconController, qsCarrierGroupControllerBuilder, featureFlags, batteryMeterViewController) }