Merge "Notifications and quicksettings scroll independently in split shade" into sc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 2c7c5cc..76925a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -21,6 +21,7 @@
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+import static com.android.systemui.util.Utils.shouldUseSplitNotificationShade;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -83,6 +84,7 @@
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
@@ -453,6 +455,7 @@
private NotificationEntry mTopHeadsUpEntry;
private long mNumHeadsUp;
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
+ private final FeatureFlags mFeatureFlags;
private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
new ExpandableView.OnHeightChangedListener() {
@@ -492,8 +495,8 @@
GroupMembershipManager groupMembershipManager,
GroupExpansionManager groupExpansionManager,
SysuiStatusBarStateController statusbarStateController,
- AmbientState ambientState
- ) {
+ AmbientState ambientState,
+ FeatureFlags featureFlags) {
super(context, attrs, 0, 0);
Resources res = getResources();
mSectionsManager = notificationSectionsManager;
@@ -530,6 +533,7 @@
mGroupMembershipManager = groupMembershipManager;
mGroupExpansionManager = groupExpansionManager;
mStatusbarStateController = statusbarStateController;
+ mFeatureFlags = featureFlags;
}
void initializeForegroundServiceSection(ForegroundServiceDungeonView fgsSectionView) {
@@ -1156,8 +1160,13 @@
if (stackStartPosition <= stackEndPosition) {
stackHeight = stackEndPosition;
} else {
- stackHeight = (int) NotificationUtils.interpolate(stackStartPosition,
- stackEndPosition, mQsExpansionFraction);
+ if (shouldUseSplitNotificationShade(mFeatureFlags, getResources())) {
+ // This prevents notifications from being collapsed when QS is expanded.
+ stackHeight = (int) height;
+ } else {
+ stackHeight = (int) NotificationUtils.interpolate(stackStartPosition,
+ stackEndPosition, mQsExpansionFraction);
+ }
}
} else {
stackHeight = (int) height;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 0b3fd16..d179b9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -196,7 +196,8 @@
new MyOnHeadsUpChangedListener();
private final HeightListener mHeightListener = new HeightListener();
private final ConfigurationListener mConfigurationListener = new ConfigurationListener();
- private final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener();
+ @VisibleForTesting final StatusBarStateListener mStatusBarStateListener =
+ new StatusBarStateListener();
private final ExpansionCallback mExpansionCallback = new ExpansionCallback();
private final BiometricUnlockController mBiometricUnlockController;
private final NotificationPanelView mView;
@@ -1852,7 +1853,7 @@
}
}
- private void setQsExpanded(boolean expanded) {
+ @VisibleForTesting void setQsExpanded(boolean expanded) {
boolean changed = mQsExpanded != expanded;
if (changed) {
mQsExpanded = expanded;
@@ -1955,8 +1956,10 @@
private void updateQsState() {
mNotificationStackScrollLayoutController.setQsExpanded(mQsExpanded);
mNotificationStackScrollLayoutController.setScrollingEnabled(
- mBarState != KEYGUARD && (!mQsExpanded
- || mQsExpansionFromOverscroll));
+ mBarState != KEYGUARD
+ && (!mQsExpanded
+ || mQsExpansionFromOverscroll
+ || Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)));
if (mKeyguardUserSwitcherController != null && mQsExpanded
&& !mStackScrollerOverscrolling) {
@@ -2236,13 +2239,16 @@
@Override
protected boolean canCollapsePanelOnTouch() {
- if (!isInSettings()) {
- return mBarState == KEYGUARD
- || mIsPanelCollapseOnQQS
- || mNotificationStackScrollLayoutController.isScrolledToBottom();
- } else {
+ if (!isInSettings() && mBarState == KEYGUARD) {
return true;
}
+
+ if (mNotificationStackScrollLayoutController.isScrolledToBottom()) {
+ return true;
+ }
+
+ return !Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)
+ && (isInSettings() || mIsPanelCollapseOnQQS);
}
@Override
@@ -3615,6 +3621,10 @@
NotificationStackScrollLayout.OnOverscrollTopChangedListener {
@Override
public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
+ // When in split shade, overscroll shouldn't carry through to QS
+ if (Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)) {
+ return;
+ }
cancelQsAnimation();
if (!mQsExpansionEnabled) {
amount = 0f;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 461f64e..84fb368 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -21,6 +21,8 @@
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
+import static com.google.common.truth.Truth.assertWithMessage;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -49,6 +51,7 @@
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
@@ -101,6 +104,7 @@
@Mock private SysuiStatusBarStateController mStatusBarStateController;
@Mock private NotificationSwipeHelper mNotificationSwipeHelper;
@Mock private NotificationStackScrollLayoutController mStackScrollLayoutController;
+ @Mock private FeatureFlags mFeatureFlags;
@Before
@UiThreadTest
@@ -139,8 +143,8 @@
mGroupMembershipManger,
mGroupExpansionManager,
mStatusBarStateController,
- mAmbientState
- );
+ mAmbientState,
+ mFeatureFlags);
mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider,
mNotificationSwipeHelper);
mStackScroller = spy(mStackScrollerInternal);
@@ -205,8 +209,8 @@
@Test
@UiThreadTest
public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() {
- final float expectedHeight[] = {0f};
- final float expectedAppear[] = {0f};
+ final float[] expectedHeight = {0f};
+ final float[] expectedAppear = {0f};
mStackScroller.addOnExpandedHeightChangedListener((height, appear) -> {
Assert.assertEquals(expectedHeight[0], height, 0);
@@ -222,6 +226,29 @@
}
@Test
+ @UiThreadTest
+ public void testSetExpandedHeight_withSplitShade_doesntInterpolateStackHeight() {
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ final int[] expectedStackHeight = {0};
+
+ mStackScroller.addOnExpandedHeightChangedListener((expandedHeight, appear) -> {
+ assertWithMessage("Given shade enabled: %s",
+ mFeatureFlags.isTwoColumnNotificationShadeEnabled())
+ .that(mStackScroller.getHeight())
+ .isEqualTo(expectedStackHeight[0]);
+ });
+
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(false);
+ expectedStackHeight[0] = 0;
+ mStackScroller.setExpandedHeight(100f);
+
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ expectedStackHeight[0] = 100;
+ mStackScroller.setExpandedHeight(100f);
+ }
+
+
+ @Test
public void manageNotifications_visible() {
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index e788a1c..b7d338c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -18,13 +18,15 @@
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -45,6 +47,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -53,6 +56,7 @@
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitch;
@@ -100,7 +104,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
@@ -116,8 +119,6 @@
@Mock
private StatusBar mStatusBar;
@Mock
- private SysuiStatusBarStateController mStatusBarStateController;
- @Mock
private NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock
private KeyguardBottomAreaView mKeyguardBottomArea;
@@ -227,7 +228,10 @@
private AmbientState mAmbientState;
@Mock
private UserManager mUserManager;
+ @Mock
+ private UiEventLogger mUiEventLogger;
+ private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -235,6 +239,8 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger);
+
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
when(mView.getResources()).thenReturn(mResources);
@@ -258,6 +264,7 @@
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
when(mKeyguardBottomArea.getLeftView()).thenReturn(mock(KeyguardAffordanceView.class));
when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class));
+ when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
when(mView.findViewById(R.id.big_clock_container)).thenReturn(mBigClockContainer);
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mView.findViewById(R.id.keyguard_status_view))
@@ -336,17 +343,19 @@
ArgumentCaptor.forClass(View.AccessibilityDelegate.class);
verify(mView).setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture());
mAccessibiltyDelegate = accessibilityDelegateArgumentCaptor.getValue();
+ mNotificationPanelViewController.mStatusBarStateController
+ .addCallback(mNotificationPanelViewController.mStatusBarStateListener);
+ mNotificationPanelViewController
+ .setHeadsUpAppearanceController(mock(HeadsUpAppearanceController.class));
}
@Test
public void testSetDozing_notifiesNsslAndStateController() {
- mNotificationPanelViewController.setDozing(true /* dozing */, true /* animate */,
+ mNotificationPanelViewController.setDozing(true /* dozing */, false /* animate */,
null /* touch */);
- InOrder inOrder = inOrder(
- mNotificationStackScrollLayoutController, mStatusBarStateController);
- inOrder.verify(mNotificationStackScrollLayoutController)
- .setDozing(eq(true), eq(true), eq(null));
- inOrder.verify(mStatusBarStateController).setDozeAmount(eq(1f), eq(true));
+ verify(mNotificationStackScrollLayoutController)
+ .setDozing(eq(true), eq(false), eq(null));
+ assertThat(mStatusBarStateController.getDozeAmount()).isEqualTo(1f);
}
@Test
@@ -489,6 +498,39 @@
assertThat(stackScrollerLayout.startToStart).isEqualTo(R.id.qs_edge_guideline);
}
+ @Test
+ public void testCanCollapsePanelOnTouch_trueForKeyGuard() {
+ mStatusBarStateController.setState(KEYGUARD);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
+ }
+
+ @Test
+ public void testCanCollapsePanelOnTouch_trueWhenScrolledToBottom() {
+ mStatusBarStateController.setState(SHADE);
+ when(mNotificationStackScrollLayoutController.isScrolledToBottom()).thenReturn(true);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
+ }
+
+ @Test
+ public void testCanCollapsePanelOnTouch_trueWhenInSettings() {
+ mStatusBarStateController.setState(SHADE);
+ mNotificationPanelViewController.setQsExpanded(true);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
+ }
+
+ @Test
+ public void testCanCollapsePanelOnTouch_falseInDualPaneShade() {
+ mStatusBarStateController.setState(SHADE);
+ when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(true);
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ mNotificationPanelViewController.setQsExpanded(true);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isFalse();
+ }
+
private View newViewWithId(int id) {
View view = new View(mContext);
view.setId(id);