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

Commit 90978f3d authored by Ahmed Mehfooz's avatar Ahmed Mehfooz Committed by Android (Google) Code Review
Browse files

Merge "[Flexi] Fix swipe from touchable status bar elements not going through...

Merge "[Flexi] Fix swipe from touchable status bar elements not going through to the shade." into main
parents 5f4f029f 5200b576
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -261,6 +261,8 @@ private constructor(
        private val touchSlop = ViewConfiguration.get(mView.context).scaledTouchSlop
        private var initialTouchX = 0f
        private var initialTouchY = 0f
        private var isIntercepting = false
        private val cachedEvents = mutableListOf<MotionEvent>()

        override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
            if (event.action == MotionEvent.ACTION_DOWN) {
@@ -274,16 +276,31 @@ private constructor(

            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    isIntercepting = false
                    clearCachedEvents()
                    initialTouchX = event.x
                    initialTouchY = event.y
                }
                MotionEvent.ACTION_MOVE -> {
                    val dy = event.y - initialTouchY
                    if (dy > touchSlop) {
                        if (!isIntercepting) {
                            isIntercepting = true
                            dispatchCachedEvents()
                        }
                        windowRootView.get().dispatchTouchEvent(event)
                        return true
                    }
                }
                MotionEvent.ACTION_UP,
                MotionEvent.ACTION_CANCEL -> {
                    clearCachedEvents()
                    isIntercepting = false
                }
            }

            if (!isIntercepting) {
                cacheEvent(event)
            }
            return false
        }
@@ -332,6 +349,20 @@ private constructor(

            return shadeViewController.handleExternalTouch(event)
        }

        private fun cacheEvent(event: MotionEvent) {
            cachedEvents.add(MotionEvent.obtain(event))
        }

        private fun dispatchCachedEvents() {
            cachedEvents.forEach { windowRootView.get()?.dispatchTouchEvent(it) }
            clearCachedEvents()
        }

        private fun clearCachedEvents() {
            cachedEvents.forEach { it.recycle() }
            cachedEvents.clear()
        }
    }

    class Factory
+56 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
@@ -420,6 +421,25 @@ class PhoneStatusBarViewControllerTest(flags: FlagsParameterization) : SysuiTest
        verify(windowRootView).dispatchTouchEvent(moveEvent)
    }

    @Test
    @EnableSceneContainer
    fun handleInterceptTouchEventFromStatusBar_swipeDown_dispatchesCachedEvents() {
        val downEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 10f, 0)
        view.onInterceptTouchEvent(downEvent)

        val moveEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 100f, 0)
        view.onInterceptTouchEvent(moveEvent)

        // Verify that the cached ACTION_DOWN and the new ACTION_MOVE events are dispatched.
        val captor = argumentCaptor<MotionEvent>()
        verify(windowRootView, times(2)).dispatchTouchEvent(captor.capture())

        val capturedEvents = captor.allValues
        assertThat(capturedEvents).hasSize(2)
        assertThat(capturedEvents[0].action).isEqualTo(MotionEvent.ACTION_DOWN)
        assertThat(capturedEvents[1].action).isEqualTo(MotionEvent.ACTION_MOVE)
    }

    @Test
    @EnableSceneContainer
    fun handleInterceptTouchEventFromStatusBar_smallSwipe_doesNotIntercept() {
@@ -446,6 +466,42 @@ class PhoneStatusBarViewControllerTest(flags: FlagsParameterization) : SysuiTest
        verify(windowRootView, never()).dispatchTouchEvent(any())
    }

    @Test
    @EnableSceneContainer
    fun handleInterceptTouchEventFromStatusBar_clearsCacheBetweenGestures() {
        // Gesture 1: A short tap/swipe that does NOT trigger interception.
        val downEvent1 = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 10f, 0)
        view.onInterceptTouchEvent(downEvent1)

        val moveEvent1 = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 15f, 0)
        view.onInterceptTouchEvent(moveEvent1)

        val upEvent1 = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 15f, 0)
        view.onInterceptTouchEvent(upEvent1)

        // Verify that no events were dispatched.
        verify(windowRootView, never()).dispatchTouchEvent(any())

        // Gesture 2: A clear swipe down that triggers interception.
        val downEvent2 = MotionEvent.obtain(100L, 100L, MotionEvent.ACTION_DOWN, 50f, 20f, 0)
        view.onInterceptTouchEvent(downEvent2)

        // Move a large amount, greater than the touch slop.
        val moveEvent2 = MotionEvent.obtain(100L, 100L, MotionEvent.ACTION_MOVE, 50f, 150f, 0)
        view.onInterceptTouchEvent(moveEvent2)

        val captor = argumentCaptor<MotionEvent>()
        verify(windowRootView, times(2)).dispatchTouchEvent(captor.capture())

        val capturedEvents = captor.allValues
        assertThat(capturedEvents).hasSize(2)

        assertThat(capturedEvents[0].action).isEqualTo(MotionEvent.ACTION_DOWN)
        assertThat(capturedEvents[0].downTime).isEqualTo(100L)
        assertThat(capturedEvents[1].action).isEqualTo(MotionEvent.ACTION_MOVE)
        assertThat(capturedEvents[1].y).isEqualTo(150f)
    }

    @Test
    fun onTouch_windowHidden_centralSurfacesNotNotified() {
        val callback = getCommandQueueCallback()