Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e41ba4c authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Update EmptyShadeView during GONE->AOD transition" into udc-qpr-dev

parents 1c18d7b8 cc70765f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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]
+24 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -633,6 +640,7 @@ public class NotificationStackScrollLayoutController {
            KeyguardBypassController keyguardBypassController,
            KeyguardInteractor keyguardInteractor,
            PrimaryBouncerInteractor primaryBouncerInteractor,
            KeyguardTransitionRepository keyguardTransitionRepo,
            ZenModeController zenModeController,
            NotificationLockscreenUserManager lockscreenUserManager,
            Optional<NotificationListViewModel> nsslViewModel,
@@ -665,6 +673,7 @@ public class NotificationStackScrollLayoutController {
            NotificationDismissibilityProvider dismissibilityProvider,
            ActivityStarter activityStarter) {
        mView = view;
        mKeyguardTransitionRepo = keyguardTransitionRepo;
        mStackStateLogger = stackLogger;
        mLogger = logger;
        mAllowLongPress = allowLongPress;
@@ -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) {
@@ -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();

@@ -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
     */
+35 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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;
@@ -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 {

@@ -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;
@@ -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
@@ -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));
        }
@@ -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,
@@ -608,6 +639,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
                mKeyguardBypassController,
                mKeyguardInteractor,
                mPrimaryBouncerInteractor,
                mKeyguardTransitionRepo,
                mZenModeController,
                mNotificationLockscreenUserManager,
                Optional.<NotificationListViewModel>empty(),