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

Commit 47b5e410 authored by Michael Mikhail's avatar Michael Mikhail
Browse files

Fix media carousel activities in RTL

This CL fixes the change in reordering, players visibility, and media
scroll handler issues in RTL.
On reordering all players, the visible player should be the rightmost player.
On playing a UMO View, onLayout method is called. It adjust the scroll
value in RTL when the view is not laid out. Therefore, we need to set
the scroll value to the relative value.
On removing a player, we need to make sure the scroll view changes the
scroll value if we are on the rightmost player in media carousel.

Bug: 289174065
Bug: 287168003
Test: Manually checked the media carousel using 3 different umos at the
same time.
Test: atest MediaCarouselScrollHandlerTest.

Change-Id: I80a32eab50d3b75cf3e617d7c8e8d961b2eb6b8a
parent 2c24ddf1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -606,6 +606,9 @@ constructor(
                }
                    ?: mediaCarouselScrollHandler.scrollToPlayer(destIndex = mediaIndex)
            }
        } else if (isRtl && mediaContent.childCount > 0) {
            // In RTL, Scroll to the first player as it is the rightmost player in media carousel.
            mediaCarouselScrollHandler.scrollToPlayer(destIndex = 0)
        }
        // Check postcondition: mediaContent should have the same number of children as there
        // are
+5 −3
Original line number Diff line number Diff line
@@ -282,13 +282,14 @@ class MediaCarouselScrollHandler(
            // It's an up and the fling didn't take it above
            val relativePos = scrollView.relativeScrollX % playerWidthPlusPadding
            val scrollXAmount: Int =
                if (isRtl xor (relativePos > playerWidthPlusPadding / 2)) {
                if (relativePos > playerWidthPlusPadding / 2) {
                    playerWidthPlusPadding - relativePos
                } else {
                    -1 * relativePos
                }
            if (scrollXAmount != 0) {
                val newScrollX = scrollView.relativeScrollX + scrollXAmount
                val dx = if (isRtl) -scrollXAmount else scrollXAmount
                val newScrollX = scrollView.scrollX + dx
                // Delay the scrolling since scrollView calls springback which cancels
                // the animation again..
                mainExecutor.execute { scrollView.smoothScrollTo(newScrollX, scrollView.scrollY) }
@@ -539,7 +540,8 @@ class MediaCarouselScrollHandler(
        // If the removed media item is "left of" the active one (in an absolute sense), we need to
        // scroll the view to keep that player in view.  This is because scroll position is always
        // calculated from left to right.
        val leftOfActive = if (isRtl) !beforeActive else beforeActive
        // For RTL, we need to scroll if the visible media player is the last item.
        val leftOfActive = if (isRtl && visibleMediaIndex != 0) !beforeActive else beforeActive
        if (leftOfActive) {
            scrollView.scrollX = Math.max(scrollView.scrollX - playerWidthPlusPadding, 0)
        }
+8 −0
Original line number Diff line number Diff line
@@ -74,6 +74,14 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
            scrollX = transformScrollX(value)
        }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        if (!isLaidOut && isLayoutRtl) {
            // Reset scroll because onLayout method overrides RTL scroll if view was not laid out.
            mScrollX = relativeScrollX
        }
        super.onLayout(changed, l, t, r, b)
    }

    /** Allow all scrolls to go through, use base implementation */
    override fun scrollTo(x: Int, y: Int) {
        if (mScrollX != x || mScrollY != y) {
+4 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
    fun testCarouselScroll_shortScroll() {
        whenever(mediaCarousel.isLayoutRtl).thenReturn(false)
        whenever(mediaCarousel.relativeScrollX).thenReturn(300)
        whenever(mediaCarousel.scrollX).thenReturn(300)

        mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
        executor.runAllReady()
@@ -96,6 +97,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
    fun testCarouselScroll_shortScroll_isRTL() {
        whenever(mediaCarousel.isLayoutRtl).thenReturn(true)
        whenever(mediaCarousel.relativeScrollX).thenReturn(300)
        whenever(mediaCarousel.scrollX).thenReturn(carouselWidth - 300)

        mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
        executor.runAllReady()
@@ -107,6 +109,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
    fun testCarouselScroll_longScroll() {
        whenever(mediaCarousel.isLayoutRtl).thenReturn(false)
        whenever(mediaCarousel.relativeScrollX).thenReturn(600)
        whenever(mediaCarousel.scrollX).thenReturn(600)

        mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
        executor.runAllReady()
@@ -118,6 +121,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
    fun testCarouselScroll_longScroll_isRTL() {
        whenever(mediaCarousel.isLayoutRtl).thenReturn(true)
        whenever(mediaCarousel.relativeScrollX).thenReturn(600)
        whenever(mediaCarousel.scrollX).thenReturn(carouselWidth - 600)

        mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
        executor.runAllReady()