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

Commit 152e4e95 authored by András Kurucz's avatar András Kurucz
Browse files

[flexiglass] Patch for the unfurl animation

When we pull down the shade from the Lockscreen, and we navigate to the
Locked shade, there are a few things happening:

 - ExpandableNotificationRow#isOnKeyguard() changes
 - ExpandableNotificationRow#getIntrinsicHeight() changes
 - NSSL#getIntrinsicStackHeight() changes
 - NSSL#mMaxDisplayedNotifications changes

In order to orchestrate the same unfurl animations every time we open
the locked shade, we need to make these changes in the same frame, and
as well request a "goToFullShade" animation from the NSSL.
To guarantee that these things are happeing together under flexiglass,
let's update them from the same flow.

Fixes: 359875442
Test: observe the LS -> Locked Shade animation
Flag: com.android.systemui.scene_container

Change-Id: I083472c936d9057544c71ab58a7162b15465f9ec
parent 4f2d2366
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -838,27 +838,26 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
        testScope.runTest {
            var notificationCount = 10
            val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
            val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
            advanceTimeBy(50L)
            showLockscreen()

            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()

            assertThat(maxNotifications).isEqualTo(10)
            assertThat(config?.maxNotifications).isEqualTo(10)

            // Also updates when directly requested (as it would from NotificationStackScrollLayout)
            notificationCount = 25
            sharedNotificationContainerInteractor.notificationStackChanged()
            advanceTimeBy(50L)
            assertThat(maxNotifications).isEqualTo(25)
            assertThat(config?.maxNotifications).isEqualTo(25)

            // Also ensure another collection starts with the same value. As an example, folding
            // then unfolding will restart the coroutine and it must get the last value immediately.
            val newMaxNotifications by
                collectLastValue(underTest.getMaxNotifications(calculateSpace))
            val newConfig by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
            advanceTimeBy(50L)
            assertThat(newMaxNotifications).isEqualTo(25)
            assertThat(newConfig?.maxNotifications).isEqualTo(25)
        }

    @Test
@@ -866,18 +865,18 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
        testScope.runTest {
            var notificationCount = 10
            val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
            val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
            advanceTimeBy(50L)
            showLockscreen()

            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()

            assertThat(maxNotifications).isEqualTo(10)
            assertThat(config?.maxNotifications).isEqualTo(10)

            // Shade expanding... still 10
            shadeTestUtil.setLockscreenShadeExpansion(0.5f)
            assertThat(maxNotifications).isEqualTo(10)
            assertThat(config?.maxNotifications).isEqualTo(10)

            notificationCount = 25

@@ -885,20 +884,20 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            shadeTestUtil.setLockscreenShadeTracking(true)

            // Should still be 10, since the user is interacting
            assertThat(maxNotifications).isEqualTo(10)
            assertThat(config?.maxNotifications).isEqualTo(10)

            shadeTestUtil.setLockscreenShadeTracking(false)
            shadeTestUtil.setLockscreenShadeExpansion(0f)

            // Stopped tracking, show 25
            assertThat(maxNotifications).isEqualTo(25)
            assertThat(config?.maxNotifications).isEqualTo(25)
        }

    @Test
    fun maxNotificationsOnShade() =
        testScope.runTest {
            val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> 10 }
            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
            val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
            advanceTimeBy(50L)

            // Show lockscreen with shade expanded
@@ -908,7 +907,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            configurationRepository.onAnyConfigurationChange()

            // -1 means No Limit
            assertThat(maxNotifications).isEqualTo(-1)
            assertThat(config?.maxNotifications).isEqualTo(-1)
        }

    @Test
+6 −1
Original line number Diff line number Diff line
@@ -1532,6 +1532,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        return mPrivateLayout.getSingleLineView();
    }

    /**
     * Whether this row is displayed over the unoccluded lockscreen. Returns false on the
     * locked shade.
     */
    public boolean isOnKeyguard() {
        return mOnKeyguard;
    }
@@ -2811,7 +2815,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        }
    }

    void setOnKeyguard(boolean onKeyguard) {
    /** @see #isOnKeyguard() */
    public void setOnKeyguard(boolean onKeyguard) {
        if (onKeyguard != mOnKeyguard) {
            boolean wasAboveShelf = isAboveShelf();
            final boolean wasExpanded = isExpanded();
+8 −3
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ColorUpdateLogger;
import com.android.systemui.statusbar.notification.FeedbackIcon;
@@ -378,15 +379,19 @@ public class ExpandableNotificationRowController implements NotifViewController
                mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
                mPluginManager.addPluginListener(mView,
                        NotificationMenuRowPlugin.class, false /* Allow multiple */);
                if (!SceneContainerFlag.isEnabled()) {
                    mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
                    mStatusBarStateController.addCallback(mStatusBarStateListener);
                }
                mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
            }

            @Override
            public void onViewDetachedFromWindow(View v) {
                mPluginManager.removePluginListener(mView);
                if (!SceneContainerFlag.isEnabled()) {
                    mStatusBarStateController.removeCallback(mStatusBarStateListener);
                }
                mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener);
            }
        });
+3 −0
Original line number Diff line number Diff line
@@ -100,6 +100,9 @@ public interface NotificationListContainer extends
     */
    void addContainerViewAt(View v, int index);

    /** Sets whether the notificatios are displayed on the unoccluded lockscreen. */
    void setOnLockscreen(boolean isOnKeyguard);

    /**
     * Sets the maximum number of notifications to display.
     *
+36 −3
Original line number Diff line number Diff line
@@ -575,6 +575,7 @@ public class NotificationStackScrollLayout
    @Nullable private SplitShadeStateController mSplitShadeStateController = null;
    private boolean mIsSmallLandscapeLockscreenEnabled = false;
    private boolean mSuppressHeightUpdates;
    private boolean mIsOnLockscreen;

    /** Pass splitShadeStateController to view and update split shade */
    public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) {
@@ -3228,9 +3229,12 @@ public class NotificationStackScrollLayout
    private void onViewAddedInternal(ExpandableView child) {
        updateHideSensitiveForChild(child);
        child.setOnHeightChangedListener(mOnChildHeightChangedListener);
        if (child instanceof ExpandableNotificationRow) {
        if (child instanceof ExpandableNotificationRow row) {
            NotificationEntry entry = ((ExpandableNotificationRow) child).getEntry();
            entry.addOnSensitivityChangedListener(mOnChildSensitivityChangedListener);
            if (SceneContainerFlag.isEnabled()) {
                row.setOnKeyguard(mIsOnLockscreen);
            }
        }
        generateAddAnimation(child, false /* fromMoreCard */);
        updateAnimationState(child);
@@ -4752,8 +4756,11 @@ public class NotificationStackScrollLayout
        }
    }

    void goToFullShade(long delay) {
        SceneContainerFlag.assertInLegacyMode();
    /**
     * Requests an animation for the next stack height update, to animate from the constrained stack
     * displayed on the lock screen, to the scrollable stack displayed in the expanded shade.
     */
    public void animateGoToFullShade(long delay) {
        mGoToFullShadeNeedsAnimation = true;
        mGoToFullShadeDelay = delay;
        mNeedsAnimation = true;
@@ -5356,12 +5363,38 @@ public class NotificationStackScrollLayout
        shelf.bind(mAmbientState, this, mController.getNotificationRoundnessManager());
    }

    /**
     * Whether the notifications are displayed over the unoccluded lockscreen. Returns false on the
     * locked shade.
     */
    public boolean isOnLockscreen() {
        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return false;
        return mIsOnLockscreen;
    }

    /** @see #isOnLockscreen() */
    public void setOnLockscreen(boolean isOnLockscreen) {
        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
        if (mIsOnLockscreen != isOnLockscreen) {
            mIsOnLockscreen = isOnLockscreen;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                if (child instanceof ExpandableNotificationRow childRow) {
                    childRow.setOnKeyguard(isOnLockscreen);
                }
            }
        }
    }

    public void setMaxDisplayedNotifications(int maxDisplayedNotifications) {
        if (mMaxDisplayedNotifications != maxDisplayedNotifications) {
            mMaxDisplayedNotifications = maxDisplayedNotifications;
            if (SceneContainerFlag.isEnabled()) {
                updateIntrinsicStackHeight();
                updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
                if (maxDisplayedNotifications == -1) {
                    animateGoToFullShade(0);
                }
            } else {
                updateContentHeight();
            }
Loading