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 7a12464bd4ff6..500de2d29d03a 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 @@ -106,7 +106,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.row.FooterView; import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView; -import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; import com.android.systemui.statusbar.notification.row.StackScrollerDecorView; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; @@ -449,12 +448,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private DismissListener mDismissListener; private DismissAllAnimationListener mDismissAllAnimationListener; private NotificationRemoteInputManager mRemoteInputManager; + private ShadeController mShadeController; private final DisplayMetrics mDisplayMetrics = Dependency.get(DisplayMetrics.class); private final LockscreenGestureLogger mLockscreenGestureLogger = Dependency.get(LockscreenGestureLogger.class); - private final VisualStabilityManager mVisualStabilityManager = - Dependency.get(VisualStabilityManager.class); protected boolean mClearAllEnabled; private Interpolator mHideXInterpolator = Interpolators.FAST_OUT_SLOW_IN; @@ -553,13 +551,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable res.getBoolean(R.bool.config_drawNotificationBackground); setOutlineProvider(mOutlineProvider); - // Blocking helper manager wants to know the expanded state, update as well. - NotificationBlockingHelperManager blockingHelperManager = - Dependency.get(NotificationBlockingHelperManager.class); - addOnExpandedHeightChangedListener((height, unused) -> { - blockingHelperManager.setNotificationShadeExpanded(height); - }); - boolean willDraw = mShouldDrawNotificationBackground || DEBUG; setWillNotDraw(!willDraw); mBackgroundPaint.setAntiAlias(true); @@ -580,9 +571,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (mFgsSectionView != null) { return; } - mFgsSectionView = fgsSectionView; - addView(mFgsSectionView, -1); } @@ -603,7 +592,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable inflateEmptyShadeView(); inflateFooterView(); - mVisualStabilityManager.setVisibilityLocationProvider(this::isInVisibleLocation); } /** @@ -1020,23 +1008,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mScrollAnchorView = scrollAnchorView; } - @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM) - public boolean isInVisibleLocation(NotificationEntry entry) { - ExpandableNotificationRow row = entry.getRow(); - ExpandableViewState childViewState = row.getViewState(); - - if (childViewState == null) { - return false; - } - if ((childViewState.location & ExpandableViewState.VISIBLE_LOCATIONS) == 0) { - return false; - } - if (row.getVisibility() != View.VISIBLE) { - return false; - } - return true; - } - @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM) private void setMaxLayoutHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; @@ -5371,9 +5342,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } if (viewsToRemove.isEmpty()) { - if (closeShade) { - Dependency.get(ShadeController.class).animateCollapsePanels( - CommandQueue.FLAG_EXCLUDE_NONE); + if (closeShade && mShadeController != null) { + mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); } return; } @@ -5409,11 +5379,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable final Runnable onSlideAwayAnimationComplete = () -> { if (closeShade) { - Dependency.get(ShadeController.class).addPostCollapseAction(() -> { + mShadeController.addPostCollapseAction(() -> { setDismissAllInProgress(false); onAnimationComplete.run(); }); - Dependency.get(ShadeController.class).animateCollapsePanels( + mShadeController.animateCollapsePanels( CommandQueue.FLAG_EXCLUDE_NONE); } else { setDismissAllInProgress(false); @@ -5697,6 +5667,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mRemoteInputManager = remoteInputManager; } + void setShadeController(ShadeController shadeController) { + mShadeController = shadeController; + } + /** * A listener that is notified when the empty space below the notifications is clicked on */ @@ -6096,7 +6070,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (!mAmbientState.isDozing() || startingChild != null) { // We have notifications, go to locked shade. - Dependency.get(ShadeController.class).goToLockedShade(startingChild); + mShadeController.goToLockedShade(startingChild); if (startingChild instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild; row.onExpandedByGesture(true /* drag down is always an open */); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 231ff2cec8f5d..ab241e6721eea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -21,11 +21,11 @@ import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_N import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; -import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE; -import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnOverscrollTopChangedListener; 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.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.canChildBeDismissed; import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY; @@ -85,6 +85,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.NotificationGroup; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.OnGroupChangeListener; +import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; @@ -95,6 +96,7 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView; +import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; import com.android.systemui.statusbar.notification.row.NotificationGuts; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationSnooze; @@ -104,6 +106,7 @@ import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -139,7 +142,6 @@ public class NotificationStackScrollLayoutController { private final ZenModeController mZenModeController; private final MetricsLogger mMetricsLogger; private final FalsingManager mFalsingManager; - private final NotificationSectionsManager mNotificationSectionsManager; private final Resources mResources; private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder; private final ScrimController mScrimController; @@ -153,6 +155,9 @@ public class NotificationStackScrollLayoutController { private final ForegroundServiceSectionController mFgServicesSectionController; private final LayoutInflater mLayoutInflater; private final NotificationRemoteInputManager mRemoteInputManager; + private final VisualStabilityManager mVisualStabilityManager; + private final NotificationBlockingHelperManager mNotificationBlockingHelperManager; + private final ShadeController mShadeController; private final KeyguardMediaController mKeyguardMediaController; private final SysuiStatusBarStateController mStatusBarStateController; private final KeyguardBypassController mKeyguardBypassController; @@ -559,7 +564,6 @@ public class NotificationStackScrollLayoutController { NotificationLockscreenUserManager lockscreenUserManager, MetricsLogger metricsLogger, FalsingManager falsingManager, - NotificationSectionsManager notificationSectionsManager, @Main Resources resources, NotificationSwipeHelper.Builder notificationSwipeHelperBuilder, StatusBar statusBar, @@ -576,7 +580,10 @@ public class NotificationStackScrollLayoutController { ForegroundServiceDismissalFeatureController fgFeatureController, ForegroundServiceSectionController fgServicesSectionController, LayoutInflater layoutInflater, - NotificationRemoteInputManager remoteInputManager) { + NotificationRemoteInputManager remoteInputManager, + VisualStabilityManager visualStabilityManager, + NotificationBlockingHelperManager notificationBlockingHelperManager, + ShadeController shadeController) { mAllowLongPress = allowLongPress; mNotificationGutsManager = notificationGutsManager; mHeadsUpManager = headsUpManager; @@ -592,14 +599,12 @@ public class NotificationStackScrollLayoutController { mLockscreenUserManager = lockscreenUserManager; mMetricsLogger = metricsLogger; mFalsingManager = falsingManager; - mNotificationSectionsManager = notificationSectionsManager; mResources = resources; mNotificationSwipeHelperBuilder = notificationSwipeHelperBuilder; mStatusBar = statusBar; mScrimController = scrimController; - groupManager.registerGroupExpansionChangeListener((changedRow, expanded) -> { - mView.onGroupExpandChanged(changedRow, expanded); - }); + groupManager.registerGroupExpansionChangeListener( + (changedRow, expanded) -> mView.onGroupExpandChanged(changedRow, expanded)); legacyGroupManager.registerGroupChangeListener(new OnGroupChangeListener() { @Override public void onGroupCreatedFromChildren(NotificationGroup group) { @@ -622,6 +627,9 @@ public class NotificationStackScrollLayoutController { mFgServicesSectionController = fgServicesSectionController; mLayoutInflater = layoutInflater; mRemoteInputManager = remoteInputManager; + mVisualStabilityManager = visualStabilityManager; + mNotificationBlockingHelperManager = notificationBlockingHelperManager; + mShadeController = shadeController; } public void attach(NotificationStackScrollLayout view) { @@ -635,6 +643,7 @@ public class NotificationStackScrollLayoutController { mView.setFooterDismissListener(() -> mMetricsLogger.action(MetricsEvent.ACTION_DISMISS_ALL_NOTES)); mView.setRemoteInputManager(mRemoteInputManager); + mView.setShadeController(mShadeController); if (mFgFeatureController.isForegroundServiceDismissalEnabled()) { mView.initializeForegroundServiceSection( @@ -681,6 +690,12 @@ public class NotificationStackScrollLayoutController { mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate); mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded); + mVisualStabilityManager.setVisibilityLocationProvider(this::isInVisibleLocation); + // Blocking helper manager wants to know the expanded state, update as well. + mView.addOnExpandedHeightChangedListener((height, unused) -> + mNotificationBlockingHelperManager.setNotificationShadeExpanded(height) + ); + mTunerService.addTunable( (key, newValue) -> { switch (key) { @@ -723,6 +738,22 @@ public class NotificationStackScrollLayoutController { mSilentHeaderController.setOnClearAllClickListener(v -> clearSilentNotifications()); } + private boolean isInVisibleLocation(NotificationEntry entry) { + ExpandableNotificationRow row = entry.getRow(); + ExpandableViewState childViewState = row.getViewState(); + + if (childViewState == null) { + return false; + } + if ((childViewState.location & ExpandableViewState.VISIBLE_LOCATIONS) == 0) { + return false; + } + if (row.getVisibility() != View.VISIBLE) { + return false; + } + return true; + } + public void addOnExpandedHeightChangedListener(BiConsumer listener) { mView.addOnExpandedHeightChangedListener(listener); } @@ -1459,7 +1490,7 @@ public class NotificationStackScrollLayoutController { @Override public boolean isInVisibleLocation(NotificationEntry entry) { - return mView.isInVisibleLocation(entry); + return NotificationStackScrollLayoutController.this.isInVisibleLocation(entry); } @Override 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 0d283ce039608..5bef2573b48a1 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 @@ -3,7 +3,10 @@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,7 +34,6 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -65,6 +67,7 @@ import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -117,7 +120,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { 1, UserHandle.USER_CURRENT); // Inject dependencies before initializing the layout - mDependency.injectMockDependency(VisualStabilityManager.class); mDependency.injectTestDependency( NotificationBlockingHelperManager.class, mBlockingHelperManager); @@ -217,12 +219,20 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Test @UiThreadTest public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() { - mStackScroller.setExpandedHeight(0f); - verify(mBlockingHelperManager).setNotificationShadeExpanded(0f); - reset(mBlockingHelperManager); + final float expectedHeight[] = {0f}; + final float expectedAppear[] = {0f}; - mStackScroller.setExpandedHeight(100f); - verify(mBlockingHelperManager).setNotificationShadeExpanded(100f); + mStackScroller.addOnExpandedHeightChangedListener((height, appear) -> { + Assert.assertEquals(expectedHeight[0], height, 0); + Assert.assertEquals(expectedAppear[0], appear, .1); + }); + expectedHeight[0] = 1f; + expectedAppear[0] = 1f; + mStackScroller.setExpandedHeight(expectedHeight[0]); + + expectedHeight[0] = 100f; + expectedAppear[0] = 0f; + mStackScroller.setExpandedHeight(expectedHeight[0]); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java index d83417638cc57..74a57bf7cc55a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -60,14 +61,17 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; +import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView; +import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; @@ -83,6 +87,8 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.function.BiConsumer; + /** * Tests for {@link NotificationStackScrollLayoutController}. */ @@ -105,7 +111,6 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager; @Mock private MetricsLogger mMetricsLogger; @Mock private FalsingManager mFalsingManager; - @Mock private NotificationSectionsManager mNotificationSectionsManager; @Mock private Resources mResources; @Mock(answer = Answers.RETURNS_SELF) private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder; @@ -126,6 +131,9 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { @Mock private LayoutInflater mLayoutInflater; @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; + @Mock private VisualStabilityManager mVisualStabilityManager; + @Mock private NotificationBlockingHelperManager mNotificationBlockingHelperManager; + @Mock private ShadeController mShadeController; @Captor private ArgumentCaptor mStateListenerArgumentCaptor; @@ -158,7 +166,6 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { mNotificationLockscreenUserManager, mMetricsLogger, mFalsingManager, - mNotificationSectionsManager, mResources, mNotificationSwipeHelperBuilder, mStatusBar, @@ -175,7 +182,10 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { mFgFeatureController, mFgServicesSectionController, mLayoutInflater, - mRemoteInputManager + mRemoteInputManager, + mVisualStabilityManager, + mNotificationBlockingHelperManager, + mShadeController ); when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true); @@ -368,6 +378,25 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { any(ForegroundServiceDungeonView.class)); } + @Test + public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() { + + ArgumentCaptor> + onExpandedHeightChangeListenerCaptor = ArgumentCaptor.forClass( + BiConsumer.class); + + mController.attach(mNotificationStackScrollLayout); + + verify(mNotificationStackScrollLayout, times(2)).addOnExpandedHeightChangedListener( + onExpandedHeightChangeListenerCaptor.capture()); + + for (BiConsumer listener : + onExpandedHeightChangeListenerCaptor.getAllValues()) { + listener.accept(1f, 2f); + } + verify(mNotificationBlockingHelperManager).setNotificationShadeExpanded(1f); + } + private LogMaker logMatcher(int category, int type) { return argThat(new LogMatcher(category, type)); }