Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java +13 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shade.ShadeStateEvents; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; Loading Loading @@ -62,6 +63,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, private final HeadsUpManager mHeadsUpManager; private final ShadeStateEvents mShadeStateEvents; private final StatusBarStateController mStatusBarStateController; private final VisibilityLocationProvider mVisibilityLocationProvider; private final VisualStabilityProvider mVisualStabilityProvider; private final WakefulnessLifecycle mWakefulnessLifecycle; Loading Loading @@ -94,9 +96,11 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, HeadsUpManager headsUpManager, ShadeStateEvents shadeStateEvents, StatusBarStateController statusBarStateController, VisibilityLocationProvider visibilityLocationProvider, VisualStabilityProvider visualStabilityProvider, WakefulnessLifecycle wakefulnessLifecycle) { mHeadsUpManager = headsUpManager; mVisibilityLocationProvider = visibilityLocationProvider; mVisualStabilityProvider = visualStabilityProvider; mWakefulnessLifecycle = wakefulnessLifecycle; mStatusBarStateController = statusBarStateController; Loading @@ -123,6 +127,11 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, // HUNs to the top of the shade private final NotifStabilityManager mNotifStabilityManager = new NotifStabilityManager("VisualStabilityCoordinator") { private boolean canMoveForHeadsUp(NotificationEntry entry) { return entry != null && mHeadsUpManager.isAlerting(entry.getKey()) && !mVisibilityLocationProvider.isInVisibleLocation(entry); } @Override public void onBeginRun() { mIsSuppressingPipelineRun = false; Loading @@ -140,7 +149,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, @Override public boolean isGroupChangeAllowed(@NonNull NotificationEntry entry) { final boolean isGroupChangeAllowedForEntry = mReorderingAllowed || mHeadsUpManager.isAlerting(entry.getKey()); mReorderingAllowed || canMoveForHeadsUp(entry); mIsSuppressingGroupChange |= !isGroupChangeAllowedForEntry; return isGroupChangeAllowedForEntry; } Loading @@ -156,7 +165,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, public boolean isSectionChangeAllowed(@NonNull NotificationEntry entry) { final boolean isSectionChangeAllowedForEntry = mReorderingAllowed || mHeadsUpManager.isAlerting(entry.getKey()) || canMoveForHeadsUp(entry) || mEntriesThatCanChangeSection.containsKey(entry.getKey()); if (!isSectionChangeAllowedForEntry) { mEntriesWithSuppressedSectionChange.add(entry.getKey()); Loading @@ -165,8 +174,8 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, } @Override public boolean isEntryReorderingAllowed(@NonNull ListEntry section) { return mReorderingAllowed; public boolean isEntryReorderingAllowed(@NonNull ListEntry entry) { return mReorderingAllowed || canMoveForHeadsUp(entry.getRepresentativeEntry()); } @Override Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisibilityLocationProviderDelegator.kt 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * 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 * * 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. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.statusbar.notification.collection.provider import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.VisibilityLocationProvider import com.android.systemui.statusbar.notification.collection.NotificationEntry import javax.inject.Inject /** * An injectable component which delegates the visibility location computation to a delegate which * can be initialized after the initial injection, generally because it's provided by a view. */ @SysUISingleton class VisibilityLocationProviderDelegator @Inject constructor() : VisibilityLocationProvider { private var delegate: VisibilityLocationProvider? = null fun setDelegate(provider: VisibilityLocationProvider) { delegate = provider } override fun isInVisibleLocation(entry: NotificationEntry): Boolean = requireNotNull(this.delegate) { "delegate not initialized" }.isInVisibleLocation(entry) } packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +7 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.systemui.shade.ShadeEventsModule; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.notification.AssistantFeedbackController; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl; Loading @@ -51,6 +52,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.OnUserIn import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl; import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; Loading Loading @@ -151,6 +153,11 @@ public interface NotificationsModule { @Binds NotifGutsViewManager bindNotifGutsViewManager(NotificationGutsManager notificationGutsManager); /** Provides an instance of {@link VisibilityLocationProvider} */ @Binds VisibilityLocationProvider bindVisibilityLocationProvider( VisibilityLocationProviderDelegator visibilityLocationProviderDelegator); /** Provides an instance of {@link NotificationLogger} */ @SysUISingleton @Provides Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +6 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import com.android.systemui.statusbar.notification.collection.PipelineDumpable; import com.android.systemui.statusbar.notification.collection.PipelineDumper; 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.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.NotifStackController; import com.android.systemui.statusbar.notification.collection.render.NotifStats; Loading Loading @@ -157,6 +158,7 @@ public class NotificationStackScrollLayoutController { private final NotifCollection mNotifCollection; private final UiEventLogger mUiEventLogger; private final NotificationRemoteInputManager mRemoteInputManager; private final VisibilityLocationProviderDelegator mVisibilityLocationProviderDelegator; private final ShadeController mShadeController; private final KeyguardMediaController mKeyguardMediaController; private final SysuiStatusBarStateController mStatusBarStateController; Loading Loading @@ -638,6 +640,7 @@ public class NotificationStackScrollLayoutController { ShadeTransitionController shadeTransitionController, UiEventLogger uiEventLogger, NotificationRemoteInputManager remoteInputManager, VisibilityLocationProviderDelegator visibilityLocationProviderDelegator, ShadeController shadeController, InteractionJankMonitor jankMonitor, StackStateLogger stackLogger, Loading Loading @@ -679,6 +682,7 @@ public class NotificationStackScrollLayoutController { mNotifCollection = notifCollection; mUiEventLogger = uiEventLogger; mRemoteInputManager = remoteInputManager; mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator; mShadeController = shadeController; mFeatureFlags = featureFlags; mNotificationTargetsHelper = notificationTargetsHelper; Loading Loading @@ -750,6 +754,8 @@ public class NotificationStackScrollLayoutController { mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate); mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded); mVisibilityLocationProviderDelegator.setDelegate(this::isInVisibleLocation); mTunerService.addTunable( (key, newValue) -> { switch (key) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; import static org.junit.Assert.assertTrue; Loading @@ -38,6 +40,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shade.ShadeStateEvents; import com.android.systemui.shade.ShadeStateEvents.ShadeStateEventsListener; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotifPipeline; Loading Loading @@ -73,6 +76,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Mock private Pluggable.PluggableListener<NotifStabilityManager> mInvalidateListener; @Mock private HeadsUpManager mHeadsUpManager; @Mock private ShadeStateEvents mShadeStateEvents; @Mock private VisibilityLocationProvider mVisibilityLocationProvider; @Mock private VisualStabilityProvider mVisualStabilityProvider; @Captor private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefulnessObserverCaptor; Loading Loading @@ -100,6 +104,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { mHeadsUpManager, mShadeStateEvents, mStatusBarStateController, mVisibilityLocationProvider, mVisualStabilityProvider, mWakefulnessLifecycle); Loading Loading @@ -354,6 +359,38 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { verifyStabilityManagerWasInvalidated(times(1)); } @Test public void testMovingVisibleHeadsUpNotAllowed() { // GIVEN stability enforcing conditions setPanelExpanded(true); setSleepy(false); // WHEN a notification is alerting and visible when(mHeadsUpManager.isAlerting(mEntry.getKey())).thenReturn(true); when(mVisibilityLocationProvider.isInVisibleLocation(any(NotificationEntry.class))) .thenReturn(true); // VERIFY the notification cannot be reordered assertThat(mNotifStabilityManager.isEntryReorderingAllowed(mEntry)).isFalse(); assertThat(mNotifStabilityManager.isSectionChangeAllowed(mEntry)).isFalse(); } @Test public void testMovingInvisibleHeadsUpAllowed() { // GIVEN stability enforcing conditions setPanelExpanded(true); setSleepy(false); // WHEN a notification is alerting but not visible when(mHeadsUpManager.isAlerting(mEntry.getKey())).thenReturn(true); when(mVisibilityLocationProvider.isInVisibleLocation(any(NotificationEntry.class))) .thenReturn(false); // VERIFY the notification can be reordered assertThat(mNotifStabilityManager.isEntryReorderingAllowed(mEntry)).isTrue(); assertThat(mNotifStabilityManager.isSectionChangeAllowed(mEntry)).isTrue(); } @Test public void testNeverSuppressedChanges_noInvalidationCalled() { // GIVEN no notifications are currently being suppressed from grouping nor being sorted Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java +13 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shade.ShadeStateEvents; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; Loading Loading @@ -62,6 +63,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, private final HeadsUpManager mHeadsUpManager; private final ShadeStateEvents mShadeStateEvents; private final StatusBarStateController mStatusBarStateController; private final VisibilityLocationProvider mVisibilityLocationProvider; private final VisualStabilityProvider mVisualStabilityProvider; private final WakefulnessLifecycle mWakefulnessLifecycle; Loading Loading @@ -94,9 +96,11 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, HeadsUpManager headsUpManager, ShadeStateEvents shadeStateEvents, StatusBarStateController statusBarStateController, VisibilityLocationProvider visibilityLocationProvider, VisualStabilityProvider visualStabilityProvider, WakefulnessLifecycle wakefulnessLifecycle) { mHeadsUpManager = headsUpManager; mVisibilityLocationProvider = visibilityLocationProvider; mVisualStabilityProvider = visualStabilityProvider; mWakefulnessLifecycle = wakefulnessLifecycle; mStatusBarStateController = statusBarStateController; Loading @@ -123,6 +127,11 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, // HUNs to the top of the shade private final NotifStabilityManager mNotifStabilityManager = new NotifStabilityManager("VisualStabilityCoordinator") { private boolean canMoveForHeadsUp(NotificationEntry entry) { return entry != null && mHeadsUpManager.isAlerting(entry.getKey()) && !mVisibilityLocationProvider.isInVisibleLocation(entry); } @Override public void onBeginRun() { mIsSuppressingPipelineRun = false; Loading @@ -140,7 +149,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, @Override public boolean isGroupChangeAllowed(@NonNull NotificationEntry entry) { final boolean isGroupChangeAllowedForEntry = mReorderingAllowed || mHeadsUpManager.isAlerting(entry.getKey()); mReorderingAllowed || canMoveForHeadsUp(entry); mIsSuppressingGroupChange |= !isGroupChangeAllowedForEntry; return isGroupChangeAllowedForEntry; } Loading @@ -156,7 +165,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, public boolean isSectionChangeAllowed(@NonNull NotificationEntry entry) { final boolean isSectionChangeAllowedForEntry = mReorderingAllowed || mHeadsUpManager.isAlerting(entry.getKey()) || canMoveForHeadsUp(entry) || mEntriesThatCanChangeSection.containsKey(entry.getKey()); if (!isSectionChangeAllowedForEntry) { mEntriesWithSuppressedSectionChange.add(entry.getKey()); Loading @@ -165,8 +174,8 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, } @Override public boolean isEntryReorderingAllowed(@NonNull ListEntry section) { return mReorderingAllowed; public boolean isEntryReorderingAllowed(@NonNull ListEntry entry) { return mReorderingAllowed || canMoveForHeadsUp(entry.getRepresentativeEntry()); } @Override Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisibilityLocationProviderDelegator.kt 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * 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 * * 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. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.statusbar.notification.collection.provider import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.VisibilityLocationProvider import com.android.systemui.statusbar.notification.collection.NotificationEntry import javax.inject.Inject /** * An injectable component which delegates the visibility location computation to a delegate which * can be initialized after the initial injection, generally because it's provided by a view. */ @SysUISingleton class VisibilityLocationProviderDelegator @Inject constructor() : VisibilityLocationProvider { private var delegate: VisibilityLocationProvider? = null fun setDelegate(provider: VisibilityLocationProvider) { delegate = provider } override fun isInVisibleLocation(entry: NotificationEntry): Boolean = requireNotNull(this.delegate) { "delegate not initialized" }.isInVisibleLocation(entry) }
packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +7 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.systemui.shade.ShadeEventsModule; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.notification.AssistantFeedbackController; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl; Loading @@ -51,6 +52,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.OnUserIn import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl; import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; Loading Loading @@ -151,6 +153,11 @@ public interface NotificationsModule { @Binds NotifGutsViewManager bindNotifGutsViewManager(NotificationGutsManager notificationGutsManager); /** Provides an instance of {@link VisibilityLocationProvider} */ @Binds VisibilityLocationProvider bindVisibilityLocationProvider( VisibilityLocationProviderDelegator visibilityLocationProviderDelegator); /** Provides an instance of {@link NotificationLogger} */ @SysUISingleton @Provides Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +6 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import com.android.systemui.statusbar.notification.collection.PipelineDumpable; import com.android.systemui.statusbar.notification.collection.PipelineDumper; 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.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.NotifStackController; import com.android.systemui.statusbar.notification.collection.render.NotifStats; Loading Loading @@ -157,6 +158,7 @@ public class NotificationStackScrollLayoutController { private final NotifCollection mNotifCollection; private final UiEventLogger mUiEventLogger; private final NotificationRemoteInputManager mRemoteInputManager; private final VisibilityLocationProviderDelegator mVisibilityLocationProviderDelegator; private final ShadeController mShadeController; private final KeyguardMediaController mKeyguardMediaController; private final SysuiStatusBarStateController mStatusBarStateController; Loading Loading @@ -638,6 +640,7 @@ public class NotificationStackScrollLayoutController { ShadeTransitionController shadeTransitionController, UiEventLogger uiEventLogger, NotificationRemoteInputManager remoteInputManager, VisibilityLocationProviderDelegator visibilityLocationProviderDelegator, ShadeController shadeController, InteractionJankMonitor jankMonitor, StackStateLogger stackLogger, Loading Loading @@ -679,6 +682,7 @@ public class NotificationStackScrollLayoutController { mNotifCollection = notifCollection; mUiEventLogger = uiEventLogger; mRemoteInputManager = remoteInputManager; mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator; mShadeController = shadeController; mFeatureFlags = featureFlags; mNotificationTargetsHelper = notificationTargetsHelper; Loading Loading @@ -750,6 +754,8 @@ public class NotificationStackScrollLayoutController { mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate); mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded); mVisibilityLocationProviderDelegator.setDelegate(this::isInVisibleLocation); mTunerService.addTunable( (key, newValue) -> { switch (key) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; import static org.junit.Assert.assertTrue; Loading @@ -38,6 +40,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shade.ShadeStateEvents; import com.android.systemui.shade.ShadeStateEvents.ShadeStateEventsListener; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotifPipeline; Loading Loading @@ -73,6 +76,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Mock private Pluggable.PluggableListener<NotifStabilityManager> mInvalidateListener; @Mock private HeadsUpManager mHeadsUpManager; @Mock private ShadeStateEvents mShadeStateEvents; @Mock private VisibilityLocationProvider mVisibilityLocationProvider; @Mock private VisualStabilityProvider mVisualStabilityProvider; @Captor private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefulnessObserverCaptor; Loading Loading @@ -100,6 +104,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { mHeadsUpManager, mShadeStateEvents, mStatusBarStateController, mVisibilityLocationProvider, mVisualStabilityProvider, mWakefulnessLifecycle); Loading Loading @@ -354,6 +359,38 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { verifyStabilityManagerWasInvalidated(times(1)); } @Test public void testMovingVisibleHeadsUpNotAllowed() { // GIVEN stability enforcing conditions setPanelExpanded(true); setSleepy(false); // WHEN a notification is alerting and visible when(mHeadsUpManager.isAlerting(mEntry.getKey())).thenReturn(true); when(mVisibilityLocationProvider.isInVisibleLocation(any(NotificationEntry.class))) .thenReturn(true); // VERIFY the notification cannot be reordered assertThat(mNotifStabilityManager.isEntryReorderingAllowed(mEntry)).isFalse(); assertThat(mNotifStabilityManager.isSectionChangeAllowed(mEntry)).isFalse(); } @Test public void testMovingInvisibleHeadsUpAllowed() { // GIVEN stability enforcing conditions setPanelExpanded(true); setSleepy(false); // WHEN a notification is alerting but not visible when(mHeadsUpManager.isAlerting(mEntry.getKey())).thenReturn(true); when(mVisibilityLocationProvider.isInVisibleLocation(any(NotificationEntry.class))) .thenReturn(false); // VERIFY the notification can be reordered assertThat(mNotifStabilityManager.isEntryReorderingAllowed(mEntry)).isTrue(); assertThat(mNotifStabilityManager.isSectionChangeAllowed(mEntry)).isTrue(); } @Test public void testNeverSuppressedChanges_noInvalidationCalled() { // GIVEN no notifications are currently being suppressed from grouping nor being sorted Loading