Merge "Moving adjusting constraints to NotificationsQSContainerController" into tm-dev

This commit is contained in:
Michał Brzeziński
2022-03-09 10:16:31 +00:00
committed by Android (Google) Code Review
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;
@@ -1080,14 +1076,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 =
@@ -1097,49 +1089,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);
@@ -1150,15 +1105,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
}
}