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:
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user