Moving adjusting constraints to NotificationsQSContainerController

That obviously forced other changes as well like moving several tests from NotificationPanelViewControllerTest to NotificationQSContainerControllerTest.
The next nice improvement would be moving all constrains changes to NotificationsQSContainerController

Bug: 222482227
Test: just refactoring
Change-Id: I1d94fd06e79d01342979dfaf60db12e5529a9ade
This commit is contained in:
Michal Brzezinski
2022-03-04 16:42:54 +00:00
parent cdb9f0c8aa
commit 5ed6e969cc
5 changed files with 241 additions and 198 deletions

View File

@@ -18,13 +18,9 @@ package com.android.systemui.statusbar.phone;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.view.View.GONE;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static androidx.constraintlayout.widget.ConstraintSet.BOTTOM;
import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
import static androidx.constraintlayout.widget.ConstraintSet.START;
import static androidx.constraintlayout.widget.ConstraintSet.TOP;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
@@ -1070,14 +1066,10 @@ public class NotificationPanelViewController extends PanelViewController {
public void updateResources() {
mQuickQsOffsetHeight = SystemBarUtils.getQuickQsOffsetHeight(mView.getContext());
mSplitShadeStatusBarHeight = Utils.getSplitShadeStatusBarHeight(mView.getContext());
mSplitShadeNotificationsScrimMarginBottom =
mResources.getDimensionPixelSize(
R.dimen.split_shade_notifications_scrim_margin_bottom);
int panelMarginHorizontal = mResources.getDimensionPixelSize(
R.dimen.notification_panel_margin_horizontal);
final boolean newShouldUseSplitNotificationShade =
Utils.shouldUseSplitNotificationShade(mResources);
final boolean splitNotificationShadeChanged =
@@ -1087,49 +1079,12 @@ public class NotificationPanelViewController extends PanelViewController {
if (mQs != null) {
mQs.setInSplitShade(mShouldUseSplitNotificationShade);
}
int notificationsBottomMargin = mResources.getDimensionPixelSize(
R.dimen.notification_panel_margin_bottom);
mSplitShadeStatusBarHeight = Utils.getSplitShadeStatusBarHeight(mView.getContext());
int topMargin = mShouldUseSplitNotificationShade ? mSplitShadeStatusBarHeight :
mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top);
mSplitShadeHeaderController.setSplitShadeMode(mShouldUseSplitNotificationShade);
// To change the constraints at runtime, all children of the ConstraintLayout must have ids
ensureAllViewsHaveIds(mNotificationContainerParent);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(mNotificationContainerParent);
int statusViewMarginHorizontal = mResources.getDimensionPixelSize(
R.dimen.status_view_margin_horizontal);
constraintSet.setMargin(R.id.keyguard_status_view, START, statusViewMarginHorizontal);
constraintSet.setMargin(R.id.keyguard_status_view, END, statusViewMarginHorizontal);
if (mShouldUseSplitNotificationShade) {
// width = 0 to take up all available space within constraints
constraintSet.connect(R.id.qs_frame, END, R.id.qs_edge_guideline, END);
constraintSet.connect(
R.id.notification_stack_scroller, START,
R.id.qs_edge_guideline, START);
constraintSet.constrainHeight(R.id.split_shade_status_bar, mSplitShadeStatusBarHeight);
} else {
constraintSet.connect(R.id.qs_frame, END, PARENT_ID, END);
constraintSet.connect(R.id.notification_stack_scroller, START, PARENT_ID, START);
if (mUseCombinedQSHeaders) {
constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT);
}
}
constraintSet.setMargin(R.id.notification_stack_scroller, START,
mShouldUseSplitNotificationShade ? 0 : panelMarginHorizontal);
constraintSet.setMargin(R.id.notification_stack_scroller, END, panelMarginHorizontal);
constraintSet.setMargin(R.id.notification_stack_scroller, TOP, topMargin);
constraintSet.setMargin(R.id.notification_stack_scroller, BOTTOM,
notificationsBottomMargin);
constraintSet.setMargin(R.id.qs_frame, START, panelMarginHorizontal);
constraintSet.setMargin(R.id.qs_frame, END,
mShouldUseSplitNotificationShade ? 0 : panelMarginHorizontal);
constraintSet.setMargin(R.id.qs_frame, TOP, topMargin);
constraintSet.applyTo(mNotificationContainerParent);
mAmbientState.setStackTopMargin(topMargin);
mNotificationsQSContainerController.updateMargins();
mNotificationsQSContainerController.setSplitShadeEnabled(mShouldUseSplitNotificationShade);
mNotificationsQSContainerController.updateResources();
updateKeyguardStatusViewAlignment(/* animate= */false);
@@ -1140,15 +1095,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
private static void ensureAllViewsHaveIds(ViewGroup parentView) {
for (int i = 0; i < parentView.getChildCount(); i++) {
View childView = parentView.getChildAt(i);
if (childView.getId() == View.NO_ID) {
childView.setId(View.generateViewId());
}
}
}
private View reInflateStub(int viewId, int stubId, int layoutId, boolean enabled) {
View view = mView.findViewById(viewId);
if (view != null) {

View File

@@ -1,6 +1,15 @@
package com.android.systemui.statusbar.phone
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowInsets
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
import androidx.constraintlayout.widget.ConstraintSet.END
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.constraintlayout.widget.ConstraintSet.TOP
import com.android.systemui.R
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -10,6 +19,7 @@ import com.android.systemui.plugins.qs.QSContainerController
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.util.Utils
import com.android.systemui.util.ViewController
import java.util.function.Consumer
import javax.inject.Inject
@@ -28,23 +38,20 @@ class NotificationsQSContainerController @Inject constructor(
mView.invalidate()
}
}
var splitShadeEnabled = false
set(value) {
if (field != value) {
field = value
// in case device configuration changed while showing QS details/customizer
updateBottomSpacing()
}
}
private var splitShadeEnabled = false
private var isQSDetailShowing = false
private var isQSCustomizing = false
private var isQSCustomizerAnimating = false
private var splitShadeStatusBarHeight = 0
private var notificationsBottomMargin = 0
private var scrimShadeBottomMargin = 0
private var bottomStableInsets = 0
private var bottomCutoutInsets = 0
private var panelMarginHorizontal = 0
private var topMargin = 0
private val useCombinedQSHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
private var isGestureNavigation = true
private var taskbarVisible = false
@@ -68,7 +75,6 @@ class NotificationsQSContainerController @Inject constructor(
}
public override fun onViewAttached() {
updateMargins()
updateResources()
overviewProxyService.addCallback(taskbarVisibilityListener)
mView.setInsetsChangedListener(windowInsetsListener)
@@ -83,7 +89,27 @@ class NotificationsQSContainerController @Inject constructor(
mView.setConfigurationChangedListener(null)
}
private fun updateResources() {
fun updateResources() {
val newSplitShadeEnabled = Utils.shouldUseSplitNotificationShade(resources)
val splitShadeEnabledChanged = newSplitShadeEnabled != splitShadeEnabled
splitShadeEnabled = newSplitShadeEnabled
notificationsBottomMargin = resources.getDimensionPixelSize(
R.dimen.notification_panel_margin_bottom)
splitShadeStatusBarHeight = Utils.getSplitShadeStatusBarHeight(context)
panelMarginHorizontal = resources.getDimensionPixelSize(
R.dimen.notification_panel_margin_horizontal)
topMargin = if (splitShadeEnabled) {
splitShadeStatusBarHeight
} else {
resources.getDimensionPixelSize(R.dimen.notification_panel_margin_top)
}
updateConstraints()
if (splitShadeEnabledChanged) {
// Let's do it at the end when all margins/paddings were already applied.
// We need to updateBottomSpacing() in case device configuration changed while showing
// QS details/customizer
updateBottomSpacing()
}
val previousScrimShadeBottomMargin = scrimShadeBottomMargin
scrimShadeBottomMargin = resources.getDimensionPixelSize(
R.dimen.split_shade_notifications_scrim_margin_bottom
@@ -94,15 +120,6 @@ class NotificationsQSContainerController @Inject constructor(
}
}
/**
* Update the notification bottom margin.
*
* Will not call updateBottomSpacing
*/
fun updateMargins() {
notificationsBottomMargin = mView.defaultNotificationsMarginBottom
}
override fun setCustomizerAnimating(animating: Boolean) {
if (isQSCustomizerAnimating != animating) {
isQSCustomizerAnimating = animating
@@ -178,4 +195,66 @@ class NotificationsQSContainerController @Inject constructor(
}
return containerPadding to stackScrollMargin
}
}
fun updateConstraints() {
// To change the constraints at runtime, all children of the ConstraintLayout must have ids
ensureAllViewsHaveIds(mView)
val constraintSet = ConstraintSet()
constraintSet.clone(mView)
setKeyguardStatusViewConstraints(constraintSet)
setQsConstraints(constraintSet)
setNotificationsConstraints(constraintSet)
setSplitShadeStatusBarConstraints(constraintSet)
mView.applyConstraints(constraintSet)
}
private fun setSplitShadeStatusBarConstraints(constraintSet: ConstraintSet) {
if (splitShadeEnabled) {
constraintSet.constrainHeight(R.id.split_shade_status_bar, splitShadeStatusBarHeight)
} else {
if (useCombinedQSHeaders) {
constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT)
}
}
}
private fun setNotificationsConstraints(constraintSet: ConstraintSet) {
val startConstraintId = if (splitShadeEnabled) R.id.qs_edge_guideline else PARENT_ID
constraintSet.apply {
connect(R.id.notification_stack_scroller, START, startConstraintId, START)
setMargin(R.id.notification_stack_scroller, START,
if (splitShadeEnabled) 0 else panelMarginHorizontal)
setMargin(R.id.notification_stack_scroller, END, panelMarginHorizontal)
setMargin(R.id.notification_stack_scroller, TOP, topMargin)
setMargin(R.id.notification_stack_scroller, BOTTOM, notificationsBottomMargin)
}
}
private fun setQsConstraints(constraintSet: ConstraintSet) {
val endConstraintId = if (splitShadeEnabled) R.id.qs_edge_guideline else PARENT_ID
constraintSet.apply {
connect(R.id.qs_frame, END, endConstraintId, END)
setMargin(R.id.qs_frame, START, panelMarginHorizontal)
setMargin(R.id.qs_frame, END, if (splitShadeEnabled) 0 else panelMarginHorizontal)
setMargin(R.id.qs_frame, TOP, topMargin)
}
}
private fun setKeyguardStatusViewConstraints(constraintSet: ConstraintSet) {
val statusViewMarginHorizontal = resources.getDimensionPixelSize(
R.dimen.status_view_margin_horizontal)
constraintSet.apply {
setMargin(R.id.keyguard_status_view, START, statusViewMarginHorizontal)
setMargin(R.id.keyguard_status_view, END, statusViewMarginHorizontal)
}
}
private fun ensureAllViewsHaveIds(parentView: ViewGroup) {
for (i in 0 until parentView.childCount) {
val childView = parentView.getChildAt(i)
if (childView.id == View.NO_ID) {
childView.id = View.generateViewId()
}
}
}
}

View File

@@ -26,6 +26,7 @@ import android.view.WindowInsets;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import com.android.systemui.R;
import com.android.systemui.fragments.FragmentHostManager;
@@ -123,10 +124,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
}
}
public int getDefaultNotificationsMarginBottom() {
return ((LayoutParams) mStackScroller.getLayoutParams()).bottomMargin;
}
public void setInsetsChangedListener(Consumer<WindowInsets> onInsetsChangedListener) {
mInsetsChangedListener = onInsetsChangedListener;
}
@@ -197,4 +194,7 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
}
}
public void applyConstraints(ConstraintSet constraintSet) {
constraintSet.applyTo(this);
}
}

View File

@@ -56,13 +56,11 @@ import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.test.filters.SmallTest;
@@ -389,8 +387,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame));
mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller));
mNotificationContainerParent.addView(mKeyguardStatusView);
mNotificationContainerParent.onFinishInflate();
when(mView.findViewById(R.id.notification_container_parent))
@@ -678,31 +674,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
verify(mStatusBarKeyguardViewManager).showBouncer(true);
}
@Test
public void testAllChildrenOfNotificationContainer_haveIds() {
enableSplitShade(/* enabled= */ true);
mNotificationContainerParent.removeAllViews();
mNotificationContainerParent.addView(newViewWithId(1));
mNotificationContainerParent.addView(newViewWithId(View.NO_ID));
mNotificationPanelViewController.updateResources();
assertThat(mNotificationContainerParent.getChildAt(0).getId()).isEqualTo(1);
assertThat(mNotificationContainerParent.getChildAt(1).getId()).isNotEqualTo(View.NO_ID);
}
@Test
public void testSinglePaneShadeLayout_isAlignedToParent() {
enableSplitShade(/* enabled= */ false);
mNotificationPanelViewController.updateResources();
assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
.isEqualTo(ConstraintSet.PARENT_ID);
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
.isEqualTo(ConstraintSet.PARENT_ID);
}
@Test
public void testKeyguardStatusViewInSplitShade_changesConstraintsDependingOnNotifications() {
mStatusBarStateController.setState(KEYGUARD);
@@ -751,46 +722,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
verify(mUserSwitcherStubView).inflate();
}
@Test
public void testSplitShadeLayout_isAlignedToGuideline() {
enableSplitShade(/* enabled= */ true);
mNotificationPanelViewController.updateResources();
assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
.isEqualTo(R.id.qs_edge_guideline);
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
.isEqualTo(R.id.qs_edge_guideline);
}
@Test
public void testSplitShadeLayout_childrenHaveInsideMarginsOfZero() {
enableSplitShade(/* enabled= */ true);
mNotificationPanelViewController.updateResources();
assertThat(getConstraintSetLayout(R.id.qs_frame).startMargin).isEqualTo(10);
assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(0);
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startMargin)
.isEqualTo(0);
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).endMargin)
.isEqualTo(10);
}
@Test
public void testSinglePaneLayout_childrenHaveEqualMargins() {
enableSplitShade(/* enabled= */ false);
mNotificationPanelViewController.updateResources();
assertThat(getConstraintSetLayout(R.id.qs_frame).startMargin).isEqualTo(10);
assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(10);
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startMargin)
.isEqualTo(10);
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).endMargin)
.isEqualTo(10);
}
@Test
public void testCanCollapsePanelOnTouch_trueForKeyGuard() {
mStatusBarStateController.setState(KEYGUARD);
@@ -1016,17 +947,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
}
}
private View newViewWithId(int id) {
View view = new View(mContext);
view.setId(id);
ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// required as cloning ConstraintSet fails if view doesn't have layout params
view.setLayoutParams(layoutParams);
return view;
}
private ConstraintSet.Layout getConstraintSetLayout(@IdRes int id) {
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(mNotificationContainerParent);

View File

@@ -1,9 +1,14 @@
package com.android.systemui.statusbar.phone
import android.annotation.IdRes
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowManagerPolicyConstants
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -13,6 +18,7 @@ import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -58,46 +64,54 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
lateinit var taskbarVisibilityCaptor: ArgumentCaptor<OverviewProxyListener>
@Captor
lateinit var windowInsetsCallbackCaptor: ArgumentCaptor<Consumer<WindowInsets>>
@Captor
lateinit var constraintSetCaptor: ArgumentCaptor<ConstraintSet>
private lateinit var notificationsQSContainerController: NotificationsQSContainerController
private lateinit var controller: NotificationsQSContainerController
private lateinit var navigationModeCallback: ModeChangedListener
private lateinit var taskbarVisibilityCallback: OverviewProxyListener
private lateinit var windowInsetsCallback: Consumer<WindowInsets>
private val testableResources = mContext.orCreateTestableResources
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
mContext.ensureTestableResources()
whenever(notificationsQSContainer.context).thenReturn(mContext)
whenever(notificationsQSContainer.resources).thenReturn(mContext.resources)
notificationsQSContainerController = NotificationsQSContainerController(
controller = NotificationsQSContainerController(
notificationsQSContainer,
navigationModeController,
overviewProxyService,
featureFlags
)
mContext.orCreateTestableResources
.addOverride(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
whenever(notificationsQSContainer.defaultNotificationsMarginBottom)
.thenReturn(NOTIFICATIONS_MARGIN)
overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
overrideResource(R.dimen.notification_panel_margin_bottom, NOTIFICATIONS_MARGIN)
overrideResource(R.bool.config_use_split_notification_shade, false)
whenever(navigationModeController.addListener(navigationModeCaptor.capture()))
.thenReturn(GESTURES_NAVIGATION)
doNothing().`when`(overviewProxyService).addCallback(taskbarVisibilityCaptor.capture())
doNothing().`when`(notificationsQSContainer)
.setInsetsChangedListener(windowInsetsCallbackCaptor.capture())
doNothing().`when`(notificationsQSContainer).applyConstraints(constraintSetCaptor.capture())
notificationsQSContainerController.init()
notificationsQSContainerController.onViewAttached()
controller.init()
controller.onViewAttached()
navigationModeCallback = navigationModeCaptor.value
taskbarVisibilityCallback = taskbarVisibilityCaptor.value
windowInsetsCallback = windowInsetsCallbackCaptor.value
}
fun overrideResource(@IdRes id: Int, value: Any) {
mContext.orCreateTestableResources.addOverride(id, value)
}
@Test
fun testTaskbarVisibleInSplitShade() {
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
useNewFooter(false)
given(taskbarVisible = true,
@@ -115,7 +129,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarVisibleInSplitShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
useNewFooter(true)
given(taskbarVisible = true,
@@ -136,7 +150,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSplitShade() {
// when taskbar is not visible, it means we're on the home screen
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
useNewFooter(false)
given(taskbarVisible = false,
@@ -154,7 +168,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSplitShade_newFooter() {
// when taskbar is not visible, it means we're on the home screen
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
useNewFooter(true)
given(taskbarVisible = false,
@@ -173,7 +187,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSplitShadeWithCutout() {
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
useNewFooter(false)
given(taskbarVisible = false,
@@ -190,7 +204,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSplitShadeWithCutout_newFooter() {
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
useNewFooter(true)
given(taskbarVisible = false,
@@ -209,7 +223,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarVisibleInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
disableSplitShade()
useNewFooter(false)
given(taskbarVisible = true,
@@ -225,7 +239,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarVisibleInSinglePaneShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = false
disableSplitShade()
useNewFooter(true)
given(taskbarVisible = true,
@@ -243,7 +257,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
disableSplitShade()
useNewFooter(false)
given(taskbarVisible = false,
@@ -264,7 +278,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testTaskbarNotVisibleInSinglePaneShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = false
disableSplitShade()
useNewFooter(true)
given(taskbarVisible = false,
@@ -285,8 +299,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testCustomizingInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
notificationsQSContainerController.setCustomizerShowing(true)
disableSplitShade()
controller.setCustomizerShowing(true)
useNewFooter(false)
// always sets spacings to 0
@@ -305,8 +319,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testCustomizingInSinglePaneShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = false
notificationsQSContainerController.setCustomizerShowing(true)
disableSplitShade()
controller.setCustomizerShowing(true)
useNewFooter(true)
// always sets spacings to 0
@@ -325,8 +339,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testDetailShowingInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
notificationsQSContainerController.setDetailShowing(true)
disableSplitShade()
controller.setDetailShowing(true)
useNewFooter(false)
// always sets spacings to 0
@@ -345,8 +359,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testDetailShowingInSinglePaneShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = false
notificationsQSContainerController.setDetailShowing(true)
disableSplitShade()
controller.setDetailShowing(true)
useNewFooter(true)
// always sets spacings to 0
@@ -365,8 +379,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testDetailShowingInSplitShade() {
notificationsQSContainerController.splitShadeEnabled = true
notificationsQSContainerController.setDetailShowing(true)
enableSplitShade()
controller.setDetailShowing(true)
useNewFooter(false)
given(taskbarVisible = false,
@@ -383,8 +397,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testDetailShowingInSplitShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = true
notificationsQSContainerController.setDetailShowing(true)
enableSplitShade()
controller.setDetailShowing(true)
useNewFooter(true)
given(taskbarVisible = false,
@@ -402,16 +416,86 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testNotificationsMarginBottomIsUpdated() {
Mockito.clearInvocations(notificationsQSContainer)
notificationsQSContainerController.splitShadeEnabled = true
enableSplitShade()
verify(notificationsQSContainer).setNotificationsMarginBottom(NOTIFICATIONS_MARGIN)
whenever(notificationsQSContainer.defaultNotificationsMarginBottom).thenReturn(100)
notificationsQSContainerController.updateMargins()
notificationsQSContainerController.splitShadeEnabled = false
overrideResource(R.dimen.notification_panel_margin_bottom, 100)
disableSplitShade()
verify(notificationsQSContainer).setNotificationsMarginBottom(100)
}
@Test
fun testSplitShadeLayout_isAlignedToGuideline() {
enableSplitShade()
controller.updateResources()
assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
.isEqualTo(R.id.qs_edge_guideline)
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
.isEqualTo(R.id.qs_edge_guideline)
}
@Test
fun testSinglePaneLayout_childrenHaveEqualMargins() {
disableSplitShade()
controller.updateResources()
val qsStartMargin = getConstraintSetLayout(R.id.qs_frame).startMargin
val qsEndMargin = getConstraintSetLayout(R.id.qs_frame).endMargin
val notifStartMargin = getConstraintSetLayout(R.id.notification_stack_scroller).startMargin
val notifEndMargin = getConstraintSetLayout(R.id.notification_stack_scroller).endMargin
assertThat(qsStartMargin == qsEndMargin &&
notifStartMargin == notifEndMargin &&
qsStartMargin == notifStartMargin
).isTrue()
}
@Test
fun testSplitShadeLayout_childrenHaveInsideMarginsOfZero() {
enableSplitShade()
controller.updateResources()
assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(0)
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startMargin)
.isEqualTo(0)
}
@Test
fun testSinglePaneShadeLayout_isAlignedToParent() {
disableSplitShade()
controller.updateResources()
assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
.isEqualTo(ConstraintSet.PARENT_ID)
assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
.isEqualTo(ConstraintSet.PARENT_ID)
}
@Test
fun testAllChildrenOfNotificationContainer_haveIds() {
// set dimen to 0 to avoid triggering updating bottom spacing
overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, 0)
val container = NotificationsQuickSettingsContainer(context, null)
container.removeAllViews()
container.addView(newViewWithId(1))
container.addView(newViewWithId(View.NO_ID))
val controller = NotificationsQSContainerController(container, navigationModeController,
overviewProxyService, featureFlags)
controller.updateResources()
assertThat(container.getChildAt(0).id).isEqualTo(1)
assertThat(container.getChildAt(1).id).isNotEqualTo(View.NO_ID)
}
private fun disableSplitShade() {
setSplitShadeEnabled(false)
}
private fun enableSplitShade() {
setSplitShadeEnabled(true)
}
private fun setSplitShadeEnabled(enabled: Boolean) {
overrideResource(R.bool.config_use_split_notification_shade, enabled)
controller.updateResources()
}
private fun given(
taskbarVisible: Boolean,
navigationMode: Int,
@@ -458,4 +542,18 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
private fun useNewFooter(useNewFooter: Boolean) {
whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(useNewFooter)
}
}
private fun getConstraintSetLayout(@IdRes id: Int): ConstraintSet.Layout {
return constraintSetCaptor.value.getConstraint(id).layout
}
private fun newViewWithId(id: Int): View {
val view = View(mContext)
view.id = id
val layoutParams = ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
// required as cloning ConstraintSet fails if view doesn't have layout params
view.layoutParams = layoutParams
return view
}
}