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

Commit 2bea2264 authored by Lucas Silva's avatar Lucas Silva Committed by Android (Google) Code Review
Browse files

Merge "Enable fullscreen swipe by default" into main

parents ccf93234 e392fc8e
Loading
Loading
Loading
Loading
+0 −7
Original line number 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 {
  name: "glanceable_hub_shortcut_button"
  namespace: "systemui"
+2 −21
Original line number Diff line number Diff line
@@ -32,15 +32,12 @@ import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.ElementKey
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.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneKey
@@ -52,7 +49,6 @@ import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
import com.android.compose.theme.LocalAndroidColorScheme
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.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -61,7 +57,6 @@ import com.android.systemui.communal.ui.compose.extensions.allowGestures
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.CommunalColors
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.ui.composable.SceneTransitionLayoutDataSource
import kotlin.time.DurationUnit
@@ -191,25 +186,11 @@ fun CommunalContainer(
        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(
        state = state,
        modifier = modifier.fillMaxSize(),
        swipeSourceDetector = swipeSourceDetector,
        swipeDetector = swipeDetector,
        swipeSourceDetector = detector,
        swipeDetector = detector,
    ) {
        scene(
            CommunalScenes.Blank,
+9 −33
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.theme.PlatformTheme
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.dagger.AmbientTouchComponent
import com.android.systemui.communal.dagger.Communal
@@ -309,13 +308,9 @@ constructor(
        )
        collectFlow(containerView, keyguardInteractor.isDreaming, { isDreaming = it })

        if (glanceableHubFullscreenSwipe()) {
        communalContainerWrapper = CommunalWrapper(containerView.context)
        communalContainerWrapper?.addView(communalContainerView)
        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
        // the touch.
        if (
            glanceableHubFullscreenSwipe() &&
            !hubShowing &&
                !notificationStackScrollLayoutController.isBelowLastNotification(ev.x, ev.y)
        ) {
@@ -389,18 +383,8 @@ constructor(
        val hubOccluded = anyBouncerShowing || shadeShowing

        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
        }
            }
        }

        if (isTrackingHubTouch) {
            if (isUp || isCancel) {
@@ -419,20 +403,12 @@ constructor(
    private fun dispatchTouchEvent(view: View, ev: MotionEvent): Boolean {
        try {
            var handled = false
            if (glanceableHubFullscreenSwipe()) {
            communalContainerWrapper?.dispatchTouchEvent(ev) {
                if (it) {
                    handled = true
                }
            }
            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 {
            powerManager.userActivity(
                SystemClock.uptimeMillis(),
+0 −140
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.systemui.shade

import android.graphics.Rect
import android.os.PowerManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
@@ -29,10 +27,8 @@ import android.widget.FrameLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambient.touch.TouchHandler
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.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
@@ -70,8 +64,6 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
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
    fun lifecycle_initializedAfterConstruction() =
        with(kosmos) {
@@ -517,7 +382,6 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
        }

    @Test
    @EnableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
    fun fullScreenSwipeGesture_doNotProcessTouchesInNotificationStack() =
        with(kosmos) {
            testScope.runTest {
@@ -572,9 +436,5 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() {
                CONTAINER_HEIGHT.toFloat() / 2,
                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)
    }
}