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

Commit c1ac283d authored by William Xiao's avatar William Xiao Committed by Android (Google) Code Review
Browse files

Merge "Forward CommunalContainer touches when hub mode closed" into main

parents 8ed669d5 c7f9b63e
Loading
Loading
Loading
Loading
+56 −23
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
@@ -19,8 +20,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.ElementKey
@@ -28,6 +31,7 @@ import com.android.compose.animation.scene.FixedSizeEdgeDetector
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.transitions
@@ -56,6 +60,7 @@ val sceneTransitions = transitions {
 * This is a temporary container to allow the communal UI to use [SceneTransitionLayout] for gesture
 * handling and transitions before the full Flexiglass layout is ready.
 */
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun CommunalContainer(
    modifier: Modifier = Modifier,
@@ -65,6 +70,7 @@ fun CommunalContainer(
        viewModel.currentScene
            .transform<CommunalSceneKey, SceneKey> { value -> value.toTransitionSceneKey() }
            .collectAsState(TransitionSceneKey.Blank)
    val sceneTransitionLayoutState = remember { SceneTransitionLayoutState(currentScene) }
    // Don't show hub mode UI if keyguard is present. This is important since we're in the shade,
    // which can be opened from many locations.
    val isKeyguardShowing by viewModel.isKeyguardVisible.collectAsState(initial = false)
@@ -75,18 +81,21 @@ fun CommunalContainer(
        return
    }

    Box(modifier = modifier.fillMaxSize()) {
        SceneTransitionLayout(
        modifier = modifier.fillMaxSize(),
            modifier = Modifier.fillMaxSize(),
            currentScene = currentScene,
            onChangeScene = { sceneKey -> viewModel.onSceneChanged(sceneKey.toCommunalSceneKey()) },
            transitions = sceneTransitions,
            state = sceneTransitionLayoutState,
            edgeDetector = FixedSizeEdgeDetector(ContainerDimensions.EdgeSwipeSize)
        ) {
            scene(
                TransitionSceneKey.Blank,
                userActions =
                    mapOf(
                    Swipe(SwipeDirection.Left, fromEdge = Edge.Right) to TransitionSceneKey.Communal
                        Swipe(SwipeDirection.Left, fromEdge = Edge.Right) to
                            TransitionSceneKey.Communal
                    )
            ) {
                BlankScene { showSceneTransitionLayout = false }
@@ -96,12 +105,36 @@ fun CommunalContainer(
                TransitionSceneKey.Communal,
                userActions =
                    mapOf(
                    Swipe(SwipeDirection.Right, fromEdge = Edge.Left) to TransitionSceneKey.Blank
                        Swipe(SwipeDirection.Right, fromEdge = Edge.Left) to
                            TransitionSceneKey.Blank
                    ),
            ) {
                CommunalScene(viewModel, modifier = modifier)
            }
        }

        // TODO(b/308813166): remove once CommunalContainer is moved lower in z-order and doesn't
        //  block touches anymore.
        Box(
            modifier =
                Modifier.fillMaxSize()
                    // Offsetting to the left so that edge swipe to open the hub still works. This
                    // does mean that the very right edge of the hub won't refresh the screen
                    // timeout, but should be good enough for a temporary solution.
                    .offset(x = -ContainerDimensions.EdgeSwipeSize)
                    .pointerInteropFilter {
                        viewModel.onUserActivity()
                        if (
                            sceneTransitionLayoutState.transitionState.currentScene ==
                                TransitionSceneKey.Blank
                        ) {
                            viewModel.onOuterTouch(it)
                            return@pointerInteropFilter true
                        }
                        false
                    }
        )
    }
}

/**
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.communal.view.viewmodel

import android.app.smartspace.SmartspaceTarget
import android.os.PowerManager
import android.provider.Settings
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -33,6 +34,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.media.controls.ui.MediaHost
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -50,6 +52,8 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
class CommunalEditModeViewModelTest : SysuiTestCase() {
    @Mock private lateinit var mediaHost: MediaHost
    @Mock private lateinit var shadeViewController: ShadeViewController
    @Mock private lateinit var powerManager: PowerManager

    private lateinit var testScope: TestScope

@@ -79,6 +83,8 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
        underTest =
            CommunalEditModeViewModel(
                withDeps.communalInteractor,
                shadeViewController,
                powerManager,
                mediaHost,
            )
    }
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.communal.view.viewmodel

import android.app.smartspace.SmartspaceTarget
import android.os.PowerManager
import android.provider.Settings
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -33,6 +34,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.media.controls.ui.MediaHost
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -50,6 +52,8 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
class CommunalViewModelTest : SysuiTestCase() {
    @Mock private lateinit var mediaHost: MediaHost
    @Mock private lateinit var shadeViewController: ShadeViewController
    @Mock private lateinit var powerManager: PowerManager

    private lateinit var testScope: TestScope

@@ -80,6 +84,8 @@ class CommunalViewModelTest : SysuiTestCase() {
            CommunalViewModel(
                withDeps.communalInteractor,
                withDeps.tutorialInteractor,
                shadeViewController,
                powerManager,
                mediaHost,
            )
    }
+4 −51
Original line number Diff line number Diff line
@@ -2,63 +2,16 @@ package com.android.systemui.communal.ui.view.layout.sections

import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.compose.ComposeFacade
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.view.layout.sections.removeView
import com.android.systemui.res.R
import javax.inject.Inject

/** A keyguard section that hosts the communal hub. */
class DefaultCommunalHubSection
@Inject
constructor(
    private val viewModel: CommunalViewModel,
) : KeyguardSection() {
    private val communalHubViewId = R.id.communal_hub

    override fun addViews(constraintLayout: ConstraintLayout) {
        constraintLayout.addView(
            ComposeFacade.createCommunalView(
                    context = constraintLayout.context,
                    viewModel = viewModel,
                )
                .apply { id = communalHubViewId },
        )
    }
class DefaultCommunalHubSection @Inject constructor() : KeyguardSection() {
    override fun addViews(constraintLayout: ConstraintLayout) {}

    override fun bindData(constraintLayout: ConstraintLayout) {}

    override fun applyConstraints(constraintSet: ConstraintSet) {
        constraintSet.apply {
            connect(
                communalHubViewId,
                ConstraintSet.START,
                ConstraintSet.PARENT_ID,
                ConstraintSet.START,
            )
            connect(
                communalHubViewId,
                ConstraintSet.TOP,
                ConstraintSet.PARENT_ID,
                ConstraintSet.TOP,
            )
            connect(
                communalHubViewId,
                ConstraintSet.END,
                ConstraintSet.PARENT_ID,
                ConstraintSet.END,
            )
            connect(
                communalHubViewId,
                ConstraintSet.BOTTOM,
                ConstraintSet.PARENT_ID,
                ConstraintSet.BOTTOM,
            )
        }
    }
    override fun applyConstraints(constraintSet: ConstraintSet) {}

    override fun removeViews(constraintLayout: ConstraintLayout) {
        constraintLayout.removeView(communalHubViewId)
    }
    override fun removeViews(constraintLayout: ConstraintLayout) {}
}
+26 −0
Original line number Diff line number Diff line
@@ -16,16 +16,22 @@

package com.android.systemui.communal.ui.viewmodel

import android.os.PowerManager
import android.os.SystemClock
import android.view.MotionEvent
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.media.controls.ui.MediaHost
import com.android.systemui.shade.ShadeViewController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

/** The base view model for the communal hub. */
abstract class BaseCommunalViewModel(
    private val communalInteractor: CommunalInteractor,
    private val shadeViewController: ShadeViewController,
    private val powerManager: PowerManager,
    val mediaHost: MediaHost,
) {
    val isKeyguardVisible: Flow<Boolean> = communalInteractor.isKeyguardVisible
@@ -36,6 +42,26 @@ abstract class BaseCommunalViewModel(
        communalInteractor.onSceneChanged(scene)
    }

    // TODO(b/308813166): remove once CommunalContainer is moved lower in z-order and doesn't block
    //  touches anymore.
    /** Called when a touch is received outside the edge swipe area when hub mode is closed. */
    fun onOuterTouch(motionEvent: MotionEvent) {
        // Forward the touch to the shade so that basic gestures like swipe up/down for
        // shade/bouncer work.
        shadeViewController.handleExternalTouch(motionEvent)
    }

    // TODO(b/308813166): remove once CommunalContainer is moved lower in z-order and doesn't block
    //  touches anymore.
    /** Called to refresh the screen timeout when a user touch is received. */
    fun onUserActivity() {
        powerManager.userActivity(
            SystemClock.uptimeMillis(),
            PowerManager.USER_ACTIVITY_EVENT_TOUCH,
            0
        )
    }

    /** A list of all the communal content to be displayed in the communal hub. */
    abstract val communalContent: Flow<List<CommunalContentModel>>

Loading