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

Commit e392fc8e authored by Lucas Silva's avatar Lucas Silva
Browse files

Enable fullscreen swipe by default

Removes the existing fullscreen swipe flag and enables it by default
instead when the hub is enabled.

Flag: com.android.systemui.communal_hub
Test: atest GlanceableHubContainerControllerTest
Bug: 349382367
Change-Id: I56b133821f83b48477a6452c6ae0a56497c58a31
parent 50f3273c
Loading
Loading
Loading
Loading
+0 −7
Original line number Original line Diff line number Diff line
@@ -1020,13 +1020,6 @@ flag {
  }
  }
}
}


flag {
  name: "glanceable_hub_fullscreen_swipe"
  namespace: "systemui"
  description: "Increase swipe area for gestures to bring in glanceable hub"
  bug: "339665673"
}

flag {
flag {
  name: "glanceable_hub_shortcut_button"
  name: "glanceable_hub_shortcut_button"
  namespace: "systemui"
  namespace: "systemui"
+2 −21
Original line number Original line Diff line number Diff line
@@ -31,15 +31,12 @@ import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.CommunalSwipeDetector
import com.android.compose.animation.scene.CommunalSwipeDetector
import com.android.compose.animation.scene.DefaultSwipeDetector
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementMatcher
import com.android.compose.animation.scene.ElementMatcher
import com.android.compose.animation.scene.FixedSizeEdgeDetector
import com.android.compose.animation.scene.LowestZIndexScenePicker
import com.android.compose.animation.scene.LowestZIndexScenePicker
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneKey
@@ -51,7 +48,6 @@ import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
import com.android.compose.animation.scene.transitions
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.systemui.Flags
import com.android.systemui.Flags
import com.android.systemui.Flags.glanceableHubFullscreenSwipe
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -60,7 +56,6 @@ import com.android.systemui.communal.ui.compose.extensions.allowGestures
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
import com.android.systemui.scene.ui.composable.SceneTransitionLayoutDataSource
import com.android.systemui.scene.ui.composable.SceneTransitionLayoutDataSource
import kotlin.time.DurationUnit
import kotlin.time.DurationUnit
@@ -187,25 +182,11 @@ fun CommunalContainer(
        onDispose { viewModel.setTransitionState(null) }
        onDispose { viewModel.setTransitionState(null) }
    }
    }


    val swipeSourceDetector =
        if (glanceableHubFullscreenSwipe()) {
            detector
        } else {
            FixedSizeEdgeDetector(dimensionResource(id = R.dimen.communal_gesture_initiation_width))
        }

    val swipeDetector =
        if (glanceableHubFullscreenSwipe()) {
            detector
        } else {
            DefaultSwipeDetector
        }

    SceneTransitionLayout(
    SceneTransitionLayout(
        state = state,
        state = state,
        modifier = modifier.fillMaxSize(),
        modifier = modifier.fillMaxSize(),
        swipeSourceDetector = swipeSourceDetector,
        swipeSourceDetector = detector,
        swipeDetector = swipeDetector,
        swipeDetector = detector,
    ) {
    ) {
        scene(
        scene(
            CommunalScenes.Blank,
            CommunalScenes.Blank,
+9 −33
Original line number Original line Diff line number Diff line
@@ -37,7 +37,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.theme.PlatformTheme
import com.android.compose.theme.PlatformTheme
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.Flags.glanceableHubFullscreenSwipe
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.communal.dagger.Communal
import com.android.systemui.communal.dagger.Communal
@@ -309,13 +308,9 @@ constructor(
        )
        )
        collectFlow(containerView, keyguardInteractor.isDreaming, { isDreaming = it })
        collectFlow(containerView, keyguardInteractor.isDreaming, { isDreaming = it })


        if (glanceableHubFullscreenSwipe()) {
        communalContainerWrapper = CommunalWrapper(containerView.context)
        communalContainerWrapper = CommunalWrapper(containerView.context)
        communalContainerWrapper?.addView(communalContainerView)
        communalContainerWrapper?.addView(communalContainerView)
        return communalContainerWrapper!!
        return communalContainerWrapper!!
        } else {
            return containerView
        }
    }
    }


    /**
    /**
@@ -371,7 +366,6 @@ constructor(
        // and the touch is within the horizontal notification band on the screen, do not process
        // and the touch is within the horizontal notification band on the screen, do not process
        // the touch.
        // the touch.
        if (
        if (
            glanceableHubFullscreenSwipe() &&
            !hubShowing &&
            !hubShowing &&
                !notificationStackScrollLayoutController.isBelowLastNotification(ev.x, ev.y)
                !notificationStackScrollLayoutController.isBelowLastNotification(ev.x, ev.y)
        ) {
        ) {
@@ -389,18 +383,8 @@ constructor(
        val hubOccluded = anyBouncerShowing || shadeShowing
        val hubOccluded = anyBouncerShowing || shadeShowing


        if (isDown && !hubOccluded) {
        if (isDown && !hubOccluded) {
            if (glanceableHubFullscreenSwipe()) {
                isTrackingHubTouch = true
            } else {
                val x = ev.rawX
                val inOpeningSwipeRegion: Boolean = x >= view.width - rightEdgeSwipeRegionWidth
                if (inOpeningSwipeRegion || hubShowing) {
                    // Steal touch events when the hub is open, or if the touch started in the
                    // opening gesture region.
            isTrackingHubTouch = true
            isTrackingHubTouch = true
        }
        }
            }
        }


        if (isTrackingHubTouch) {
        if (isTrackingHubTouch) {
            if (isUp || isCancel) {
            if (isUp || isCancel) {
@@ -419,20 +403,12 @@ constructor(
    private fun dispatchTouchEvent(view: View, ev: MotionEvent): Boolean {
    private fun dispatchTouchEvent(view: View, ev: MotionEvent): Boolean {
        try {
        try {
            var handled = false
            var handled = false
            if (glanceableHubFullscreenSwipe()) {
            communalContainerWrapper?.dispatchTouchEvent(ev) {
            communalContainerWrapper?.dispatchTouchEvent(ev) {
                if (it) {
                if (it) {
                    handled = true
                    handled = true
                }
                }
            }
            }
            return handled || hubShowing
            return handled || hubShowing
            } else {
                view.dispatchTouchEvent(ev)
                // Return true regardless of dispatch result as some touches at the start of a
                // gesture
                // may return false from dispatchTouchEvent.
                return true
            }
        } finally {
        } finally {
            powerManager.userActivity(
            powerManager.userActivity(
                SystemClock.uptimeMillis(),
                SystemClock.uptimeMillis(),
+0 −140
Original line number Original line Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.systemui.shade


import android.graphics.Rect
import android.graphics.Rect
import android.os.PowerManager
import android.os.PowerManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.testing.ViewUtils
@@ -29,10 +27,8 @@ import android.widget.FrameLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleOwner
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags
import com.android.systemui.Flags
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambient.touch.TouchHandler
import com.android.systemui.ambient.touch.TouchHandler
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.TouchMonitor
@@ -56,10 +52,8 @@ import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
@@ -70,8 +64,6 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.Mock
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.MockitoAnnotations


@@ -184,133 +176,6 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
            }
            }
        }
        }


    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_communalClosed_doesNotIntercept() =
        with(kosmos) {
            testScope.runTest {
                // Communal is closed.
                goToScene(CommunalScenes.Blank)

                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
            }
        }

    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_openGesture_interceptsTouches() =
        with(kosmos) {
            testScope.runTest {
                // Communal is closed.
                goToScene(CommunalScenes.Blank)

                // Initial touch down is intercepted, and so are touches outside of the region,
                // until an
                // up event is received.
                assertThat(underTest.onTouchEvent(DOWN_IN_RIGHT_SWIPE_REGION_EVENT)).isTrue()
                assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
                assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
                assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
            }
        }

    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_communalTransitioning_interceptsTouches() =
        with(kosmos) {
            testScope.runTest {
                // Communal is opening.
                communalRepository.setTransitionState(
                    flowOf(
                        ObservableTransitionState.Transition(
                            fromScene = CommunalScenes.Blank,
                            toScene = CommunalScenes.Communal,
                            currentScene = flowOf(CommunalScenes.Blank),
                            progress = flowOf(0.5f),
                            isInitiatedByUserInput = true,
                            isUserInputOngoing = flowOf(true)
                        )
                    )
                )
                testableLooper.processAllMessages()

                // Touch events are intercepted.
                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
                // User activity sent to PowerManager.
                verify(powerManager).userActivity(any(), any(), any())
            }
        }

    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_communalOpen_interceptsTouches() =
        with(kosmos) {
            testScope.runTest {
                // Communal is open.
                goToScene(CommunalScenes.Communal)

                // Touch events are intercepted.
                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
                // User activity sent to PowerManager.
                verify(powerManager).userActivity(any(), any(), any())
            }
        }

    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_communalAndBouncerShowing_doesNotIntercept() =
        with(kosmos) {
            testScope.runTest {
                // Communal is open.
                goToScene(CommunalScenes.Communal)

                // Bouncer is visible.
                fakeKeyguardBouncerRepository.setPrimaryShow(true)
                testableLooper.processAllMessages()

                // Touch events are not intercepted.
                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
                // User activity is not sent to PowerManager.
                verify(powerManager, times(0)).userActivity(any(), any(), any())
            }
        }

    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_communalAndShadeShowing_doesNotIntercept() =
        with(kosmos) {
            testScope.runTest {
                // Communal is open.
                goToScene(CommunalScenes.Communal)

                // Shade shows up.
                shadeTestUtil.setQsExpansion(1.0f)
                testableLooper.processAllMessages()

                // Touch events are not intercepted.
                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
            }
        }

    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    @Test
    fun onTouchEvent_containerViewDisposed_doesNotIntercept() =
        with(kosmos) {
            testScope.runTest {
                // Communal is open.
                goToScene(CommunalScenes.Communal)

                // Touch events are intercepted.
                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()

                // Container view disposed.
                underTest.disposeView()

                // Touch events are not intercepted.
                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
            }
        }

    @Test
    @Test
    fun lifecycle_initializedAfterConstruction() =
    fun lifecycle_initializedAfterConstruction() =
        with(kosmos) {
        with(kosmos) {
@@ -517,7 +382,6 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
        }
        }


    @Test
    @Test
    @EnableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    fun fullScreenSwipeGesture_doNotProcessTouchesInNotificationStack() =
    fun fullScreenSwipeGesture_doNotProcessTouchesInNotificationStack() =
        with(kosmos) {
        with(kosmos) {
            testScope.runTest {
            testScope.runTest {
@@ -572,9 +436,5 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
                CONTAINER_HEIGHT.toFloat() / 2,
                CONTAINER_HEIGHT.toFloat() / 2,
                0
                0
            )
            )
        private val DOWN_IN_RIGHT_SWIPE_REGION_EVENT =
            MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, CONTAINER_WIDTH.toFloat(), 0f, 0)
        private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
        private val UP_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
    }
    }
}
}