diff options
| author | 2024-02-28 13:14:50 +0000 | |
|---|---|---|
| committer | 2024-02-29 11:54:41 +0000 | |
| commit | 8fa136dadcafb504e9f370347e39b84ba87c0cfe (patch) | |
| tree | 3ccbd8e3881d0474df7beecd5399cae976bcceae | |
| parent | d0d2eb59e19a251bbe387226b1658ba9bd809463 (diff) | |
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
2 files changed, 50 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt index a39bfe00be28..68a0e9cc1bf8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -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) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt index 1687ccbf5826..3792d5c1d6b9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt @@ -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,11 +240,42 @@ 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() InstrumentationRegistry.getInstrumentation().runOnMainSync { |