summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt130
2 files changed, 140 insertions, 9 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
index ce50a11cd85d..04f05ec0b643 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
@@ -26,6 +26,7 @@ import android.view.ViewOutlineProvider
import androidx.core.view.GestureDetectorCompat
import androidx.dynamicanimation.animation.FloatPropertyCompat
import androidx.dynamicanimation.animation.SpringForce
+import com.android.internal.annotations.VisibleForTesting
import com.android.settingslib.Utils
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
@@ -148,7 +149,8 @@ class MediaCarouselScrollHandler(
}
/** The touch listener for the scroll view */
- private val touchListener =
+ @VisibleForTesting
+ val touchListener =
object : Gefingerpoken {
override fun onTouchEvent(motionEvent: MotionEvent?) = onTouch(motionEvent!!)
override fun onInterceptTouchEvent(ev: MotionEvent?) = onInterceptTouch(ev!!)
@@ -284,15 +286,14 @@ class MediaCarouselScrollHandler(
} else if (isUp || motionEvent.action == MotionEvent.ACTION_CANCEL) {
// It's an up and the fling didn't take it above
val relativePos = scrollView.relativeScrollX % playerWidthPlusPadding
- val scrollXAmount: Int
- if (relativePos > playerWidthPlusPadding / 2) {
- scrollXAmount = playerWidthPlusPadding - relativePos
- } else {
- scrollXAmount = -1 * relativePos
- }
+ val scrollXAmount: Int =
+ if (isRtl xor (relativePos > playerWidthPlusPadding / 2)) {
+ playerWidthPlusPadding - relativePos
+ } else {
+ -1 * relativePos
+ }
if (scrollXAmount != 0) {
- val dx = if (isRtl) -scrollXAmount else scrollXAmount
- val newScrollX = scrollView.relativeScrollX + dx
+ val newScrollX = scrollView.relativeScrollX + scrollXAmount
// Delay the scrolling since scrollView calls springback which cancels
// the animation again..
mainExecutor.execute { scrollView.smoothScrollTo(newScrollX, scrollView.scrollY) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt
new file mode 100644
index 000000000000..6fafb086ca9d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.media.controls.util.MediaUiEventLogger
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.PageIndicator
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner::class)
+class MediaCarouselScrollHandlerTest : SysuiTestCase() {
+
+ private val carouselWidth = 1038
+ private val motionEventUp = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0f, 0f, 0)
+
+ @Mock lateinit var mediaCarousel: MediaScrollView
+ @Mock lateinit var pageIndicator: PageIndicator
+ @Mock lateinit var dismissCallback: () -> Unit
+ @Mock lateinit var translationChangedListener: () -> Unit
+ @Mock lateinit var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit
+ @Mock lateinit var closeGuts: (immediate: Boolean) -> Unit
+ @Mock lateinit var falsingCollector: FalsingCollector
+ @Mock lateinit var falsingManager: FalsingManager
+ @Mock lateinit var logSmartspaceImpression: (Boolean) -> Unit
+ @Mock lateinit var logger: MediaUiEventLogger
+
+ lateinit var executor: FakeExecutor
+ private val clock = FakeSystemClock()
+
+ private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ executor = FakeExecutor(clock)
+ mediaCarouselScrollHandler =
+ MediaCarouselScrollHandler(
+ mediaCarousel,
+ pageIndicator,
+ executor,
+ dismissCallback,
+ translationChangedListener,
+ seekBarUpdateListener,
+ closeGuts,
+ falsingCollector,
+ falsingManager,
+ logSmartspaceImpression,
+ logger
+ )
+ mediaCarouselScrollHandler.playerWidthPlusPadding = carouselWidth
+
+ whenever(mediaCarousel.touchListener).thenReturn(mediaCarouselScrollHandler.touchListener)
+ }
+
+ @Test
+ fun testCarouselScroll_shortScroll() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(false)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(300)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(0), anyInt())
+ }
+
+ @Test
+ fun testCarouselScroll_shortScroll_isRTL() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(true)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(300)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(carouselWidth), anyInt())
+ }
+
+ @Test
+ fun testCarouselScroll_longScroll() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(false)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(600)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(carouselWidth), anyInt())
+ }
+
+ @Test
+ fun testCarouselScroll_longScroll_isRTL() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(true)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(600)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(0), anyInt())
+ }
+}