Loading packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionStep.kt +3 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.systemui.keyguard.shared.model /** This information will flow from the [KeyguardTransitionRepository] to control the UI layer */ data class TransitionStep( data class TransitionStep @JvmOverloads constructor( val from: KeyguardState = KeyguardState.OFF, val to: KeyguardState = KeyguardState.OFF, val value: Float = 0f, // constrained [0.0, 1.0] Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +24 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static com.android.systemui.statusbar.notification.stack.NotificationStac 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.phone.NotificationIconAreaController.HIGH_PRIORITY; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import android.content.res.Configuration; import android.content.res.Resources; Loading Loading @@ -64,7 +65,10 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; Loading Loading @@ -189,6 +193,7 @@ public class NotificationStackScrollLayoutController { private final GroupExpansionManager mGroupExpansionManager; private final NotifPipelineFlags mNotifPipelineFlags; private final SeenNotificationsProvider mSeenNotificationsProvider; private final KeyguardTransitionRepository mKeyguardTransitionRepo; private NotificationStackScrollLayout mView; private NotificationSwipeHelper mSwipeHelper; Loading @@ -197,6 +202,8 @@ public class NotificationStackScrollLayoutController { private int mBarState; private boolean mIsBouncerShowingFromCentralSurfaces; private HeadsUpAppearanceController mHeadsUpAppearanceController; private boolean mIsInTransitionToAod = false; private final FeatureFlags mFeatureFlags; private final NotificationTargetsHelper mNotificationTargetsHelper; private final SecureSettings mSecureSettings; Loading Loading @@ -633,6 +640,7 @@ public class NotificationStackScrollLayoutController { KeyguardBypassController keyguardBypassController, KeyguardInteractor keyguardInteractor, PrimaryBouncerInteractor primaryBouncerInteractor, KeyguardTransitionRepository keyguardTransitionRepo, ZenModeController zenModeController, NotificationLockscreenUserManager lockscreenUserManager, Optional<NotificationListViewModel> nsslViewModel, Loading Loading @@ -665,6 +673,7 @@ public class NotificationStackScrollLayoutController { NotificationDismissibilityProvider dismissibilityProvider, ActivityStarter activityStarter) { mView = view; mKeyguardTransitionRepo = keyguardTransitionRepo; mStackStateLogger = stackLogger; mLogger = logger; mAllowLongPress = allowLongPress; Loading Loading @@ -819,6 +828,9 @@ public class NotificationStackScrollLayoutController { mViewModel.ifPresent( vm -> NotificationListViewBinder .bind(mView, vm, mFalsingManager, mFeatureFlags, mNotifIconAreaController)); collectFlow(mView, mKeyguardTransitionRepo.getTransitions(), this::onKeyguardTransitionChanged); } private boolean isInVisibleLocation(NotificationEntry entry) { Loading Loading @@ -1241,10 +1253,10 @@ public class NotificationStackScrollLayoutController { final boolean shouldShow = getVisibleNotificationCount() == 0 && !mView.isQsFullScreen() // Hide empty shade view when in transition to Keyguard. // Hide empty shade view when in transition to AOD. // That avoids "No Notifications" to blink when transitioning to AOD. // For more details, see: b/228790482 && !isInTransitionToKeyguard() && !mIsInTransitionToAod // Don't show any notification content if the bouncer is showing. See b/267060171. && !isBouncerShowing(); Loading Loading @@ -1643,6 +1655,16 @@ public class NotificationStackScrollLayoutController { return shelf == null ? 0 : shelf.getIntrinsicHeight(); } @VisibleForTesting void onKeyguardTransitionChanged(TransitionStep transitionStep) { boolean isTransitionToAod = transitionStep.getFrom().equals(KeyguardState.GONE) && transitionStep.getTo().equals(KeyguardState.AOD); if (mIsInTransitionToAod != isTransitionToAod) { mIsInTransitionToAod = isTransitionToAod; updateShowEmptyShadeView(); } } /** * Enum for UiEvent logged from this class */ Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +35 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; Loading @@ -32,10 +33,14 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.FlowKt.emptyFlow; import android.content.res.Resources; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import android.view.ViewTreeObserver; import androidx.test.filters.SmallTest; Loading @@ -49,8 +54,12 @@ import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; Loading Loading @@ -105,6 +114,7 @@ import java.util.Optional; * Tests for {@link NotificationStackScrollLayoutController}. */ @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) @RunWith(AndroidTestingRunner.class) public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { Loading Loading @@ -151,6 +161,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock private NotificationIconAreaController mIconAreaController; @Mock private ActivityStarter mActivityStarter; @Mock private KeyguardTransitionRepository mKeyguardTransitionRepo; @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor; Loading @@ -162,11 +173,13 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Before public void setUp() { allowTestableLooperAsMainThread(); MockitoAnnotations.initMocks(this); mFeatureFlags.set(Flags.USE_REPOS_FOR_BOUNCER_SHOWING, false); when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper); when(mKeyguardTransitionRepo.getTransitions()).thenReturn(emptyFlow()); } @Test Loading Loading @@ -572,17 +585,33 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } @Test public void updateEmptyShadeView_onKeyguardTransitionToAod_hidesView() { initController(/* viewIsAttached= */ true); mController.onKeyguardTransitionChanged( new TransitionStep( /* from= */ KeyguardState.GONE, /* to= */ KeyguardState.AOD)); verify(mNotificationStackScrollLayout).updateEmptyShadeView(eq(false), anyBoolean()); } private LogMaker logMatcher(int category, int type) { return argThat(new LogMatcher(category, type)); } private void setupShowEmptyShadeViewState(boolean toShow) { if (toShow) { when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(SHADE); mController.onKeyguardTransitionChanged( new TransitionStep( /* from= */ KeyguardState.LOCKSCREEN, /* to= */ KeyguardState.GONE)); mController.setQsFullScreen(false); mController.getView().removeAllViews(); } else { when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD); mController.onKeyguardTransitionChanged( new TransitionStep( /* from= */ KeyguardState.GONE, /* to= */ KeyguardState.AOD)); mController.setQsFullScreen(true); mController.getView().addContainerView(mock(ExpandableNotificationRow.class)); } Loading @@ -590,7 +619,9 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { private void initController(boolean viewIsAttached) { when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(viewIsAttached); ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class); when(mNotificationStackScrollLayout.getViewTreeObserver()) .thenReturn(viewTreeObserver); mController = new NotificationStackScrollLayoutController( mNotificationStackScrollLayout, true, Loading @@ -608,6 +639,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mKeyguardBypassController, mKeyguardInteractor, mPrimaryBouncerInteractor, mKeyguardTransitionRepo, mZenModeController, mNotificationLockscreenUserManager, Optional.<NotificationListViewModel>empty(), Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionStep.kt +3 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.systemui.keyguard.shared.model /** This information will flow from the [KeyguardTransitionRepository] to control the UI layer */ data class TransitionStep( data class TransitionStep @JvmOverloads constructor( val from: KeyguardState = KeyguardState.OFF, val to: KeyguardState = KeyguardState.OFF, val value: Float = 0f, // constrained [0.0, 1.0] Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +24 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static com.android.systemui.statusbar.notification.stack.NotificationStac 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.phone.NotificationIconAreaController.HIGH_PRIORITY; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import android.content.res.Configuration; import android.content.res.Resources; Loading Loading @@ -64,7 +65,10 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; Loading Loading @@ -189,6 +193,7 @@ public class NotificationStackScrollLayoutController { private final GroupExpansionManager mGroupExpansionManager; private final NotifPipelineFlags mNotifPipelineFlags; private final SeenNotificationsProvider mSeenNotificationsProvider; private final KeyguardTransitionRepository mKeyguardTransitionRepo; private NotificationStackScrollLayout mView; private NotificationSwipeHelper mSwipeHelper; Loading @@ -197,6 +202,8 @@ public class NotificationStackScrollLayoutController { private int mBarState; private boolean mIsBouncerShowingFromCentralSurfaces; private HeadsUpAppearanceController mHeadsUpAppearanceController; private boolean mIsInTransitionToAod = false; private final FeatureFlags mFeatureFlags; private final NotificationTargetsHelper mNotificationTargetsHelper; private final SecureSettings mSecureSettings; Loading Loading @@ -633,6 +640,7 @@ public class NotificationStackScrollLayoutController { KeyguardBypassController keyguardBypassController, KeyguardInteractor keyguardInteractor, PrimaryBouncerInteractor primaryBouncerInteractor, KeyguardTransitionRepository keyguardTransitionRepo, ZenModeController zenModeController, NotificationLockscreenUserManager lockscreenUserManager, Optional<NotificationListViewModel> nsslViewModel, Loading Loading @@ -665,6 +673,7 @@ public class NotificationStackScrollLayoutController { NotificationDismissibilityProvider dismissibilityProvider, ActivityStarter activityStarter) { mView = view; mKeyguardTransitionRepo = keyguardTransitionRepo; mStackStateLogger = stackLogger; mLogger = logger; mAllowLongPress = allowLongPress; Loading Loading @@ -819,6 +828,9 @@ public class NotificationStackScrollLayoutController { mViewModel.ifPresent( vm -> NotificationListViewBinder .bind(mView, vm, mFalsingManager, mFeatureFlags, mNotifIconAreaController)); collectFlow(mView, mKeyguardTransitionRepo.getTransitions(), this::onKeyguardTransitionChanged); } private boolean isInVisibleLocation(NotificationEntry entry) { Loading Loading @@ -1241,10 +1253,10 @@ public class NotificationStackScrollLayoutController { final boolean shouldShow = getVisibleNotificationCount() == 0 && !mView.isQsFullScreen() // Hide empty shade view when in transition to Keyguard. // Hide empty shade view when in transition to AOD. // That avoids "No Notifications" to blink when transitioning to AOD. // For more details, see: b/228790482 && !isInTransitionToKeyguard() && !mIsInTransitionToAod // Don't show any notification content if the bouncer is showing. See b/267060171. && !isBouncerShowing(); Loading Loading @@ -1643,6 +1655,16 @@ public class NotificationStackScrollLayoutController { return shelf == null ? 0 : shelf.getIntrinsicHeight(); } @VisibleForTesting void onKeyguardTransitionChanged(TransitionStep transitionStep) { boolean isTransitionToAod = transitionStep.getFrom().equals(KeyguardState.GONE) && transitionStep.getTo().equals(KeyguardState.AOD); if (mIsInTransitionToAod != isTransitionToAod) { mIsInTransitionToAod = isTransitionToAod; updateShowEmptyShadeView(); } } /** * Enum for UiEvent logged from this class */ Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +35 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; Loading @@ -32,10 +33,14 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.FlowKt.emptyFlow; import android.content.res.Resources; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import android.view.ViewTreeObserver; import androidx.test.filters.SmallTest; Loading @@ -49,8 +54,12 @@ import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; Loading Loading @@ -105,6 +114,7 @@ import java.util.Optional; * Tests for {@link NotificationStackScrollLayoutController}. */ @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) @RunWith(AndroidTestingRunner.class) public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { Loading Loading @@ -151,6 +161,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock private NotificationIconAreaController mIconAreaController; @Mock private ActivityStarter mActivityStarter; @Mock private KeyguardTransitionRepository mKeyguardTransitionRepo; @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor; Loading @@ -162,11 +173,13 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Before public void setUp() { allowTestableLooperAsMainThread(); MockitoAnnotations.initMocks(this); mFeatureFlags.set(Flags.USE_REPOS_FOR_BOUNCER_SHOWING, false); when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper); when(mKeyguardTransitionRepo.getTransitions()).thenReturn(emptyFlow()); } @Test Loading Loading @@ -572,17 +585,33 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } @Test public void updateEmptyShadeView_onKeyguardTransitionToAod_hidesView() { initController(/* viewIsAttached= */ true); mController.onKeyguardTransitionChanged( new TransitionStep( /* from= */ KeyguardState.GONE, /* to= */ KeyguardState.AOD)); verify(mNotificationStackScrollLayout).updateEmptyShadeView(eq(false), anyBoolean()); } private LogMaker logMatcher(int category, int type) { return argThat(new LogMatcher(category, type)); } private void setupShowEmptyShadeViewState(boolean toShow) { if (toShow) { when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(SHADE); mController.onKeyguardTransitionChanged( new TransitionStep( /* from= */ KeyguardState.LOCKSCREEN, /* to= */ KeyguardState.GONE)); mController.setQsFullScreen(false); mController.getView().removeAllViews(); } else { when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD); mController.onKeyguardTransitionChanged( new TransitionStep( /* from= */ KeyguardState.GONE, /* to= */ KeyguardState.AOD)); mController.setQsFullScreen(true); mController.getView().addContainerView(mock(ExpandableNotificationRow.class)); } Loading @@ -590,7 +619,9 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { private void initController(boolean viewIsAttached) { when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(viewIsAttached); ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class); when(mNotificationStackScrollLayout.getViewTreeObserver()) .thenReturn(viewTreeObserver); mController = new NotificationStackScrollLayoutController( mNotificationStackScrollLayout, true, Loading @@ -608,6 +639,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mKeyguardBypassController, mKeyguardInteractor, mPrimaryBouncerInteractor, mKeyguardTransitionRepo, mZenModeController, mNotificationLockscreenUserManager, Optional.<NotificationListViewModel>empty(), Loading