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

Commit 2f9bd04d authored by Christian Göllner's avatar Christian Göllner
Browse files

Fix lockscreen shortcuts not showing on split shade

The issue was that qsVisible was wrongly being set to `true` when on
split shade, even when it was not visible.
Lockscreen shortcuts only show when QS are not visible.

To check whether QS (or QQS) was visible, we were checking:
1 - qsExpansionFraction > 0
  1.1 Split shade: true when full QS showing
  1.2 Single shade: true when full QS showing
2 - qsPanelBottomY > 0
  2.1 Split Shade: ALWAYS true. Even if QS not showing
  2.2 Single shade: true when on QQS or QS

Since on split shade we can always rely on qsExpansionFraction, because
there is no QQS, we changed the condition to ignore qsPanelBottomY
when on split shade.

Fixes: 272448562
Test: Manually on-device:
      1 - Enabled teamfood flag
      2 - Homescreen -> Wallpaper & Style
      3 - Lockscreen -> Pick 2 non-none shortcuts
      4 - Lock the screen
      5 - Verify shortcuts are visible both in single and split shade
Test: QuickSettingsControllerTest.java
Change-Id: I9adc0c4625aadcc729b484c453c6ef7d17013fc9
parent 4b4bd645
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1035,7 +1035,11 @@ public class QuickSettingsController {
    private void setClippingBounds() {
        float qsExpansionFraction = computeExpansionFraction();
        final int qsPanelBottomY = calculateBottomPosition(qsExpansionFraction);
        final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0);
        // Split shade has no QQS
        final boolean qqsVisible =
                !mSplitShadeEnabled && qsExpansionFraction == 0 && qsPanelBottomY > 0;
        final boolean qsVisible = qsExpansionFraction > 0;
        final boolean qsOrQqsVisible = qqsVisible || qsVisible;
        checkCorrectScrimVisibility(qsExpansionFraction);

        int top = calculateTopClippingBound(qsPanelBottomY);
@@ -1044,7 +1048,7 @@ public class QuickSettingsController {
        int right = calculateRightClippingBound();
        // top should never be lower than bottom, otherwise it will be invisible.
        top = Math.min(top, bottom);
        applyClippingBounds(left, top, right, bottom, qsVisible);
        applyClippingBounds(left, top, right, bottom, qsOrQqsVisible);
    }

    /**
+104 −8
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -77,7 +78,6 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
@@ -91,9 +91,12 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.List;

import dagger.Lazy;

@SmallTest
@@ -101,12 +104,14 @@ import dagger.Lazy;
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class QuickSettingsControllerTest extends SysuiTestCase {

    private static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
    private static final float QS_FRAME_START_X = 0f;
    private static final int QS_FRAME_WIDTH = 1000;
    private static final int QS_FRAME_TOP = 0;
    private static final int QS_FRAME_BOTTOM = 1000;

    private static final int DEFAULT_HEIGHT = 1000;
    // In split shade min = max
    private static final int DEFAULT_MIN_HEIGHT_SPLIT_SHADE = DEFAULT_HEIGHT;
    private static final int DEFAULT_MIN_HEIGHT = 300;

    private QuickSettingsController mQsController;

@@ -115,7 +120,6 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
    @Mock private KeyguardStatusBarView mKeyguardStatusBar;
    @Mock private QS mQs;
    @Mock private QSFragment mQSFragment;

    @Mock private Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
    @Mock private NotificationPanelViewController mNotificationPanelViewController;
    @Mock private NotificationPanelView mPanelView;
@@ -147,10 +151,7 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
    @Mock private FeatureFlags mFeatureFlags;
    @Mock private InteractionJankMonitor mInteractionJankMonitor;
    @Mock private ShadeLogger mShadeLogger;

    @Mock private DumpManager mDumpManager;

    @Mock private HeadsUpManagerPhone mHeadsUpManager;
    @Mock private UiEventLogger mUiEventLogger;

    private SysuiStatusBarStateController mStatusBarStateController;
@@ -173,6 +174,8 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
        KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
        keyguardStatusView.setId(R.id.keyguard_status_view);

        when(mResources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_qs_transition_distance)).thenReturn(DEFAULT_HEIGHT);
        when(mPanelView.getResources()).thenReturn(mResources);
        when(mPanelView.getContext()).thenReturn(getContext());
        when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
@@ -529,6 +532,88 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
        assertThat(mQsController.isOpenQsEvent(event)).isTrue();
    }

    @Test
    public void shadeClosed_onLockscreen_inSplitShade_setsQsNotVisible() {
        mQsController.setQs(mQs);
        enableSplitShade(true);
        lockScreen();

        closeLockedQS();

        assertQsVisible(false);
    }

    @Test
    public void shadeOpened_onLockscreen_inSplitShade_setsQsVisible() {
        mQsController.setQs(mQs);
        enableSplitShade(true);
        lockScreen();

        openLockedQS();

        assertQsVisible(true);
    }

    @Test
    public void shadeClosed_onLockscreen_inSingleShade_setsQsNotVisible() {
        mQsController.setQs(mQs);
        enableSplitShade(false);
        lockScreen();

        closeLockedQS();

        verify(mQs).setQsVisible(false);
    }

    @Test
    public void shadeOpened_onLockscreen_inSingleShade_setsQsVisible() {
        mQsController.setQs(mQs);
        enableSplitShade(false);
        lockScreen();

        openLockedQS();

        verify(mQs).setQsVisible(true);
    }

    private void lockScreen() {
        mQsController.setBarState(KEYGUARD);
    }

    private void openLockedQS() {
        when(mLockscreenShadeTransitionController.getQSDragProgress())
                .thenReturn((float) DEFAULT_HEIGHT);
        mLockscreenShadeTransitionCallback.setTransitionToFullShadeAmount(
                /* pxAmount= */ DEFAULT_HEIGHT,
                /* animate=*/ false,
                /* delay= */ 0
        );
    }

    private void closeLockedQS() {
        when(mLockscreenShadeTransitionController.getQSDragProgress()).thenReturn(0f);
        mLockscreenShadeTransitionCallback.setTransitionToFullShadeAmount(
                /* pxAmount= */ 0,
                /* animate=*/ false,
                /* delay= */ 0
        );
    }

    private void setSplitShadeHeightProperties() {
        // In split shade, min = max
        when(mQs.getQsMinExpansionHeight()).thenReturn(DEFAULT_MIN_HEIGHT_SPLIT_SHADE);
        when(mQs.getDesiredHeight()).thenReturn(DEFAULT_HEIGHT);
        mQsController.updateMinHeight();
        mQsController.onHeightChanged();
    }

    private void setDefaultHeightProperties() {
        when(mQs.getQsMinExpansionHeight()).thenReturn(DEFAULT_MIN_HEIGHT);
        when(mQs.getDesiredHeight()).thenReturn(DEFAULT_HEIGHT);
        mQsController.updateMinHeight();
        mQsController.onHeightChanged();
    }

    private static MotionEvent createMotionEvent(int x, int y, int action) {
        return MotionEvent.obtain(0, 0, action, x, y, 0);
    }
@@ -549,6 +634,11 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
    private void enableSplitShade(boolean enabled) {
        when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(enabled);
        mQsController.updateResources();
        if (enabled) {
            setSplitShadeHeightProperties();
        } else {
            setDefaultHeightProperties();
        }
    }

    private void setIsFullWidth(boolean fullWidth) {
@@ -561,5 +651,11 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
        mQsController.handleShadeLayoutChanged(oldMaxHeight);
    }


    private void assertQsVisible(boolean visible) {
        ArgumentCaptor<Boolean> visibilityCaptor = ArgumentCaptor.forClass(Boolean.class);
        verify(mQs, atLeastOnce()).setQsVisible(visibilityCaptor.capture());
        List<Boolean> allVisibilities = visibilityCaptor.getAllValues();
        boolean lastVisibility = allVisibilities.get(allVisibilities.size() - 1);
        assertThat(lastVisibility).isEqualTo(visible);
    }
}