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

Commit 8fa136da authored by Josh's avatar Josh
Browse files

Restricted status bar system icons touch handling to mouse events

As part of systemUI work to support mouse usage, system icons in status
bar recently became clickable and hence started handling touches, both
pointer(mouse) touches and finger touches (unintentionally). This led to
system icons container stealing touches from statusbar making it
impossible to swipe down from the system icons area to expand shade.

To fix this, we've restriced system icons container touch handling to
strictly mouse events hence all finger touch interactions stay the same
and mouse click touches are handled as intended.

Test: atest PhoneStatusBarViewControllerTest
Flag: NA
Fixes: 326097469

Change-Id: Ib1dc596311e1d8e737982cf6201a66481daef75a
parent d0d2eb59
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone
import android.app.StatusBarManager.WINDOW_STATUS_BAR
import android.graphics.Point
import android.util.Log
import android.view.InputDevice
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
@@ -81,7 +82,22 @@ private constructor(
        statusContainer.setOnHoverListener(
            statusOverlayHoverListenerFactory.createDarkAwareListener(statusContainer)
        )
        statusContainer.setOnClickListener { shadeViewController.expand(/* animate= */true) }
        statusContainer.setOnTouchListener(object : View.OnTouchListener {
            override fun onTouch(v: View, event: MotionEvent): Boolean {
                // We want to handle only mouse events here to avoid stealing finger touches from
                // status bar which expands shade when swiped down on. We're using onTouchListener
                // instead of onClickListener as the later will lead to isClickable being set to
                // true and hence ALL touches always being intercepted. See [View.OnTouchEvent]
                if (event.source == InputDevice.SOURCE_MOUSE) {
                    if (event.action == MotionEvent.ACTION_UP) {
                        v.performClick()
                        shadeViewController.expand(/* animate= */ true)
                    }
                    return true
                }
                return false
            }
        })

        progressProvider?.setReadyToHandleTransition(true)
        configurationController.addCallback(configurationListener)
+33 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.StatusBarManager.WINDOW_STATE_HIDDEN
import android.app.StatusBarManager.WINDOW_STATE_HIDING
import android.app.StatusBarManager.WINDOW_STATE_SHOWING
import android.app.StatusBarManager.WINDOW_STATUS_BAR
import android.view.InputDevice
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
@@ -239,10 +240,41 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
            controller = createAndInitController(view)
        }
        val statusContainer = view.requireViewById<View>(R.id.system_icons)
        statusContainer.performClick()
        statusContainer.dispatchTouchEvent(
            getMotionEventFromSource(
                MotionEvent.ACTION_UP,
                0,
                0,
                InputDevice.SOURCE_MOUSE
            )
        )
        verify(shadeViewController).expand(any())
    }

    @Test
    fun statusIconContainerIsNotHandlingTouchScreenTouches() {
        val view = createViewMock()
        InstrumentationRegistry.getInstrumentation().runOnMainSync {
            controller = createAndInitController(view)
        }
        val statusContainer = view.requireViewById<View>(R.id.system_icons)
        val handled = statusContainer.dispatchTouchEvent(
            getMotionEventFromSource(
                MotionEvent.ACTION_UP,
                0,
                0,
                InputDevice.SOURCE_TOUCHSCREEN
            )
        )
        assertThat(handled).isFalse()
    }

    private fun getMotionEventFromSource(action: Int, x: Int, y: Int, source: Int): MotionEvent {
        val ev = MotionEvent.obtain(0, 0, action, x.toFloat(), y.toFloat(), 0)
        ev.source = source
        return ev
    }

    @Test
    fun shadeIsNotExpandedOnStatusBarGeneralClick() {
        val view = createViewMock()