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

Commit 84018ece authored by William Xiao's avatar William Xiao
Browse files

Disable back gesture on hub directly

Previously we used gesture insets to disable the back gesture, which
seems to stop working after waking up to the hub from dozing. This CL
moves the logic directly to what the EdgeBackGestureHandler uses to
determine if back gesture should be allowed.

Bug: 363239820
Test: atest GlanceableHubContainerControllerTest QuickStepContractTest
Flag: com.android.systemui.communal_hub
Change-Id: I1dbbb7925ad650fb948f7e34806edfd71a78e421
parent 0a916863
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -345,6 +345,10 @@ public class QuickStepContract {
                || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) {
            return false;
        }
        // Disable back gesture on the hub, but not when the shade is showing.
        if ((sysuiStateFlags & SYSUI_STATE_COMMUNAL_HUB_SHOWING) != 0) {
            return (sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE) == 0;
        }
        if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
            sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN;
        }
+24 −35
Original line number Diff line number Diff line
@@ -308,6 +308,7 @@ constructor(

        communalContainerView = containerView

        if (!Flags.hubmodeFullscreenVerticalSwipeFix()) {
            val topEdgeSwipeRegionWidth =
                containerView.resources.getDimensionPixelSize(
                    R.dimen.communal_top_edge_swipe_region_height
@@ -317,26 +318,16 @@ constructor(
                    R.dimen.communal_bottom_edge_swipe_region_height
                )

        // BouncerSwipeTouchHandler has a larger gesture area than we want, set an exclusion area so
            // BouncerSwipeTouchHandler has a larger gesture area than we want, set an exclusion
            // area so
            // the gesture area doesn't overlap with widgets.
            // TODO(b/323035776): adjust gesture area for portrait mode
            containerView.repeatWhenAttached {
            // Run when the touch handling lifecycle is RESUMED, meaning the hub is visible and not
                // Run when the touch handling lifecycle is RESUMED, meaning the hub is visible and
                // not
                // occluded.
                lifecycleRegistry.repeatOnLifecycle(Lifecycle.State.RESUMED) {
                val ltr = containerView.layoutDirection == View.LAYOUT_DIRECTION_LTR

                val backGestureInset =
                    Rect(0, 0, if (ltr) 0 else containerView.right, containerView.bottom)

                    containerView.systemGestureExclusionRects =
                    if (Flags.hubmodeFullscreenVerticalSwipeFix()) {
                        listOf(
                            // Disable back gestures on the left side of the screen, to avoid
                            // conflicting with scene transitions.
                            backGestureInset
                        )
                    } else {
                        listOf(
                            // Only allow swipe up to bouncer and swipe down to shade in the very
                            // top/bottom to avoid conflicting with widgets in the hub grid.
@@ -345,17 +336,15 @@ constructor(
                                topEdgeSwipeRegionWidth,
                                containerView.right,
                                containerView.bottom - bottomEdgeSwipeRegionWidth,
                            ),
                            // Disable back gestures on the left side of the screen, to avoid
                            // conflicting with scene transitions.
                            backGestureInset,
                            )
                    }
                        )

                    logger.d({ "Insets updated: $str1" }) {
                        str1 = containerView.systemGestureExclusionRects.toString()
                    }
                }
            }
        }

        // Listen to bouncer visibility directly as these flows become true as soon as any portion
        // of the bouncers are visible when the transition starts. The keyguard transition state
+4 −62
Original line number Diff line number Diff line
@@ -449,7 +449,6 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
    fun gestureExclusionZone_setAfterInit() =
        with(kosmos) {
            testScope.runTest {
                whenever(containerView.layoutDirection).thenReturn(View.LAYOUT_DIRECTION_LTR)
                goToScene(CommunalScenes.Communal)

                assertThat(containerView.systemGestureExclusionRects)
@@ -459,13 +458,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
                            /* top= */ TOP_SWIPE_REGION_WIDTH,
                            /* right= */ CONTAINER_WIDTH,
                            /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH,
                        ),
                        Rect(
                            /* left= */ 0,
                            /* top= */ 0,
                            /* right= */ 0,
                            /* bottom= */ CONTAINER_HEIGHT,
                        ),
                        )
                    )
            }
        }
@@ -475,67 +468,14 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
    fun gestureExclusionZone_setAfterInit_fullSwipe() =
        with(kosmos) {
            testScope.runTest {
                whenever(containerView.layoutDirection).thenReturn(View.LAYOUT_DIRECTION_LTR)
                goToScene(CommunalScenes.Communal)

                assertThat(containerView.systemGestureExclusionRects)
                    .containsExactly(
                        Rect(
                            /* left= */ 0,
                            /* top= */ 0,
                            /* right= */ 0,
                            /* bottom= */ CONTAINER_HEIGHT,
                        )
                    )
                assertThat(containerView.systemGestureExclusionRects).isEmpty()
            }
        }

    @Test
    @DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
    fun gestureExclusionZone_setAfterInit_rtl() =
        with(kosmos) {
            testScope.runTest {
                whenever(containerView.layoutDirection).thenReturn(View.LAYOUT_DIRECTION_RTL)
                goToScene(CommunalScenes.Communal)

                assertThat(containerView.systemGestureExclusionRects)
                    .containsExactly(
                        Rect(
                            /* left= */ 0,
                            /* top= */ TOP_SWIPE_REGION_WIDTH,
                            /* right= */ CONTAINER_WIDTH,
                            /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH,
                        ),
                        Rect(
                            /* left= */ 0,
                            /* top= */ 0,
                            /* right= */ CONTAINER_WIDTH,
                            /* bottom= */ CONTAINER_HEIGHT,
                        ),
                    )
            }
        }

    @EnableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
    fun gestureExclusionZone_setAfterInit_rtl_fullSwipe() =
        with(kosmos) {
            testScope.runTest {
                whenever(containerView.layoutDirection).thenReturn(View.LAYOUT_DIRECTION_RTL)
                goToScene(CommunalScenes.Communal)

                assertThat(containerView.systemGestureExclusionRects)
                    .containsExactly(
                        Rect(
                            /* left= */ 0,
                            /* top= */ 0,
                            /* right= */ CONTAINER_WIDTH,
                            /* bottom= */ CONTAINER_HEIGHT,
                        )
                    )
            }
        }

    @Test
    fun gestureExclusionZone_unsetWhenShadeOpen() =
        with(kosmos) {
            testScope.runTest {
@@ -554,6 +494,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
    fun gestureExclusionZone_unsetWhenBouncerOpen() =
        with(kosmos) {
            testScope.runTest {
@@ -572,6 +513,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
    fun gestureExclusionZone_unsetWhenHubClosed() =
        with(kosmos) {
            testScope.runTest {
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.shared.system

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class QuickStepContractTest : SysuiTestCase() {
    @Test
    fun isBackGestureDisabled_hubShowing() {
        val sysuiStateFlags = SYSUI_STATE_COMMUNAL_HUB_SHOWING

        // Gestures are disabled while on the hub.
        assertThat(
                QuickStepContract.isBackGestureDisabled(sysuiStateFlags, /* forTrackpad= */ false)
            )
            .isTrue()
    }

    @Test
    fun isBackGestureDisabled_hubAndShadeShowing() {
        val sysuiStateFlags =
            SYSUI_STATE_COMMUNAL_HUB_SHOWING and SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE

        // Gestures are enabled because the shade shows over the hub.
        assertThat(
                QuickStepContract.isBackGestureDisabled(sysuiStateFlags, /* forTrackpad= */ false)
            )
            .isFalse()
    }

    @Test
    fun isBackGestureDisabled_hubAndBouncerShowing() {
        val sysuiStateFlags = SYSUI_STATE_COMMUNAL_HUB_SHOWING and SYSUI_STATE_BOUNCER_SHOWING

        // Gestures are enabled because the bouncer shows over the hub.
        assertThat(
                QuickStepContract.isBackGestureDisabled(sysuiStateFlags, /* forTrackpad= */ false)
            )
            .isFalse()
    }
}