diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/qs/QSPanel.java | 10 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt | 119 |
2 files changed, 105 insertions, 24 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 9de132f64d0b..41724ef62683 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -151,15 +151,17 @@ public class QSPanel extends LinearLayout implements Tunable { mHorizontalContentContainer.setClipChildren(true); mHorizontalContentContainer.setClipToPadding(false); // Don't clip on the top, that way, secondary pages tiles can animate up + // Clipping coordinates should be relative to this view, not absolute (parent coordinates) mHorizontalContentContainer.addOnLayoutChangeListener( (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - if (left != oldLeft || right != oldRight || bottom != oldBottom) { - mClippingRect.left = left; - mClippingRect.right = right; - mClippingRect.bottom = bottom; + if ((right - left) != (oldRight - oldLeft) + || ((bottom - top) != (oldBottom - oldTop))) { + mClippingRect.right = right - left; + mClippingRect.bottom = bottom - top; mHorizontalContentContainer.setClipBounds(mClippingRect); } }); + mClippingRect.left = 0; mClippingRect.top = -1000; mHorizontalContentContainer.setClipBounds(mClippingRect); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt index e237a5ce03fe..60cfd7249919 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt @@ -13,18 +13,24 @@ */ package com.android.systemui.qs +import android.graphics.Rect import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper +import android.testing.ViewUtils import android.view.View -import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.accessibility.AccessibilityNodeInfo import android.widget.FrameLayout import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.qs.tileimpl.QSIconViewImpl +import com.android.systemui.qs.tileimpl.QSTileViewImpl import com.google.common.truth.Truth.assertThat +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -36,37 +42,40 @@ import org.mockito.MockitoAnnotations @RunWithLooper @SmallTest class QSPanelTest : SysuiTestCase() { - private lateinit var mTestableLooper: TestableLooper - private lateinit var mQsPanel: QSPanel + private lateinit var testableLooper: TestableLooper + private lateinit var qsPanel: QSPanel - private lateinit var mParentView: ViewGroup - - private lateinit var mFooter: View + private lateinit var footer: View @Before @Throws(Exception::class) fun setup() { MockitoAnnotations.initMocks(this) - mTestableLooper = TestableLooper.get(this) + testableLooper = TestableLooper.get(this) + + testableLooper.runWithLooper { + qsPanel = QSPanel(context, null) + qsPanel.mUsingMediaPlayer = true - mTestableLooper.runWithLooper { - mQsPanel = QSPanel(mContext, null) - mQsPanel.initialize() + qsPanel.initialize() // QSPanel inflates a footer inside of it, mocking it here - mFooter = LinearLayout(mContext).apply { id = R.id.qs_footer } - mQsPanel.addView(mFooter) - mQsPanel.onFinishInflate() + footer = LinearLayout(context).apply { id = R.id.qs_footer } + qsPanel.addView(footer, MATCH_PARENT, 100) + qsPanel.onFinishInflate() // Provides a parent with non-zero size for QSPanel - mParentView = FrameLayout(mContext).apply { - addView(mQsPanel) - } + ViewUtils.attachView(qsPanel) } } + @After + fun tearDown() { + ViewUtils.detachView(qsPanel) + } + @Test fun testHasCollapseAccessibilityAction() { - val info = AccessibilityNodeInfo(mQsPanel) - mQsPanel.onInitializeAccessibilityNodeInfo(info) + val info = AccessibilityNodeInfo(qsPanel) + qsPanel.onInitializeAccessibilityNodeInfo(info) assertThat(info.actions and AccessibilityNodeInfo.ACTION_COLLAPSE).isNotEqualTo(0) assertThat(info.actions and AccessibilityNodeInfo.ACTION_EXPAND).isEqualTo(0) @@ -75,9 +84,79 @@ class QSPanelTest : SysuiTestCase() { @Test fun testCollapseActionCallsRunnable() { val mockRunnable = mock(Runnable::class.java) - mQsPanel.setCollapseExpandAction(mockRunnable) + qsPanel.setCollapseExpandAction(mockRunnable) - mQsPanel.performAccessibilityAction(AccessibilityNodeInfo.ACTION_COLLAPSE, null) + qsPanel.performAccessibilityAction(AccessibilityNodeInfo.ACTION_COLLAPSE, null) verify(mockRunnable).run() } + + @Test + fun testTilesFooterVisibleRTLLandscapeMedia() { + qsPanel.layoutDirection = View.LAYOUT_DIRECTION_RTL + // We need at least a tile so the layout has a height + qsPanel.tileLayout?.addTile( + QSPanelControllerBase.TileRecord( + mock(QSTile::class.java), + QSTileViewImpl(context, QSIconViewImpl(context)) + ) + ) + + val mediaView = FrameLayout(context) + mediaView.addView(View(context), MATCH_PARENT, 800) + + qsPanel.setUsingHorizontalLayout(/* horizontal */ true, mediaView, /* force */ true) + qsPanel.measure( + /* width */ View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.EXACTLY), + /* height */ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY) + ) + qsPanel.layout(0, 0, qsPanel.measuredWidth, qsPanel.measuredHeight) + + val tiles = qsPanel.tileLayout as View + // Tiles are effectively to the right of media + assertThat(mediaView isLeftOf tiles) + assertThat(tiles.isVisibleToUser).isTrue() + + assertThat(mediaView isLeftOf footer) + assertThat(footer.isVisibleToUser).isTrue() + } + + @Test + fun testTilesFooterVisibleLandscapeMedia() { + qsPanel.layoutDirection = View.LAYOUT_DIRECTION_LTR + // We need at least a tile so the layout has a height + qsPanel.tileLayout?.addTile( + QSPanelControllerBase.TileRecord( + mock(QSTile::class.java), + QSTileViewImpl(context, QSIconViewImpl(context)) + ) + ) + + val mediaView = FrameLayout(context) + mediaView.addView(View(context), MATCH_PARENT, 800) + + qsPanel.setUsingHorizontalLayout(/* horizontal */ true, mediaView, /* force */ true) + qsPanel.measure( + /* width */ View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.EXACTLY), + /* height */ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY) + ) + qsPanel.layout(0, 0, qsPanel.measuredWidth, qsPanel.measuredHeight) + + val tiles = qsPanel.tileLayout as View + // Tiles are effectively to the left of media + assertThat(tiles isLeftOf mediaView) + assertThat(tiles.isVisibleToUser).isTrue() + + assertThat(footer isLeftOf mediaView) + assertThat(footer.isVisibleToUser).isTrue() + } + + private infix fun View.isLeftOf(other: View): Boolean { + val rect = Rect() + getBoundsOnScreen(rect) + val thisRight = rect.right + + other.getBoundsOnScreen(rect) + + return thisRight <= rect.left + } } |