diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/qs/QSFragment.java | 21 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java | 77 |
2 files changed, 96 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 7f49bcd9d926..b5e1c5ee1a3e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -763,13 +763,32 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca @Override public int getQsMinExpansionHeight() { + if (mInSplitShade) { + return getQsMinExpansionHeightForSplitShade(); + } return mHeader.getHeight(); } + /** + * Returns the min expansion height for split shade. + * + * On split shade, QS is always expanded and goes from the top of the screen to the bottom of + * the QS container. + */ + private int getQsMinExpansionHeightForSplitShade() { + getView().getLocationOnScreen(mTemp); + int top = mTemp[1]; + // We want to get the original top position, so we subtract any translation currently set. + int originalTop = (int) (top - getView().getTranslationY()); + // On split shade the QS view doesn't start at the top of the screen, so we need to add the + // top margin. + return originalTop + getView().getHeight(); + } + @Override public void hideImmediately() { getView().animate().cancel(); - getView().setY(-mHeader.getHeight()); + getView().setY(-getQsMinExpansionHeight()); } private final ViewTreeObserver.OnPreDrawListener mStartHeaderSlidingIn diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index 777198b43d4a..63f8641ad16d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -103,8 +104,8 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { @Mock private QSPanel.QSTileLayout mQsTileLayout; @Mock private QSPanel.QSTileLayout mQQsTileLayout; @Mock private QSAnimator mQSAnimator; - private View mQsFragmentView; @Mock private StatusBarStateController mStatusBarStateController; + private View mQsFragmentView; public QSFragmentTest() { super(QSFragment.class); @@ -238,6 +239,71 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { assertThat(mQsFragmentView.getAlpha()).isEqualTo(1); } + @Test + public void getQsMinExpansionHeight_notInSplitShade_returnsHeaderHeight() { + QSFragment fragment = resumeAndGetFragment(); + disableSplitShade(); + when(mHeader.getHeight()).thenReturn(1234); + + int height = fragment.getQsMinExpansionHeight(); + + assertThat(height).isEqualTo(mHeader.getHeight()); + } + + @Test + public void getQsMinExpansionHeight_inSplitShade_returnsAbsoluteBottomOfQSContainer() { + int top = 1234; + int height = 9876; + QSFragment fragment = resumeAndGetFragment(); + enableSplitShade(); + setLocationOnScreen(mQsFragmentView, top); + when(mQsFragmentView.getHeight()).thenReturn(height); + + int expectedHeight = top + height; + assertThat(fragment.getQsMinExpansionHeight()).isEqualTo(expectedHeight); + } + + @Test + public void getQsMinExpansionHeight_inSplitShade_returnsAbsoluteBottomExcludingTranslation() { + int top = 1234; + int height = 9876; + float translationY = -600f; + QSFragment fragment = resumeAndGetFragment(); + enableSplitShade(); + setLocationOnScreen(mQsFragmentView, (int) (top + translationY)); + when(mQsFragmentView.getHeight()).thenReturn(height); + when(mQsFragmentView.getTranslationY()).thenReturn(translationY); + + int expectedHeight = top + height; + assertThat(fragment.getQsMinExpansionHeight()).isEqualTo(expectedHeight); + } + + @Test + public void hideImmediately_notInSplitShade_movesViewUpByHeaderHeight() { + QSFragment fragment = resumeAndGetFragment(); + disableSplitShade(); + when(mHeader.getHeight()).thenReturn(555); + + fragment.hideImmediately(); + + assertThat(mQsFragmentView.getY()).isEqualTo(-mHeader.getHeight()); + } + + @Test + public void hideImmediately_inSplitShade_movesViewUpByQSAbsoluteBottom() { + QSFragment fragment = resumeAndGetFragment(); + enableSplitShade(); + int top = 1234; + int height = 9876; + setLocationOnScreen(mQsFragmentView, top); + when(mQsFragmentView.getHeight()).thenReturn(height); + + fragment.hideImmediately(); + + int qsAbsoluteBottom = top + height; + assertThat(mQsFragmentView.getY()).isEqualTo(-qsAbsoluteBottom); + } + @Override protected Fragment instantiate(Context context, String className, Bundle arguments) { MockitoAnnotations.initMocks(this); @@ -332,4 +398,13 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { private void setSplitShadeEnabled(boolean enabled) { getFragment().setInSplitShade(enabled); } + + private void setLocationOnScreen(View view, int top) { + doAnswer(invocation -> { + int[] locationOnScreen = invocation.getArgument(/* index= */ 0); + locationOnScreen[0] = 0; + locationOnScreen[1] = top; + return null; + }).when(view).getLocationOnScreen(any(int[].class)); + } } |