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

Commit 73248530 authored by Coco Duan's avatar Coco Duan Committed by Android (Google) Code Review
Browse files

Merge "Motion for hub <-> edit mode transition" into main

parents 5be4d4eb b6030848
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ 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
import com.android.systemui.communal.ui.compose.Dimensions.SlideOffsetY
import com.android.systemui.communal.ui.compose.extensions.allowGestures
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.CommunalColors
@@ -76,6 +77,15 @@ object AllElements : ElementMatcher {
    override fun matches(key: ElementKey, scene: SceneKey) = true
}

private object TransitionDuration {
    const val BETWEEN_HUB_AND_EDIT_MODE_MS = 1000
    const val EDIT_MODE_TO_HUB_CONTENT_MS = 167
    const val EDIT_MODE_TO_HUB_GRID_DELAY_MS = 167
    const val EDIT_MODE_TO_HUB_GRID_END_MS =
        EDIT_MODE_TO_HUB_GRID_DELAY_MS + EDIT_MODE_TO_HUB_CONTENT_MS
    const val HUB_TO_EDIT_MODE_CONTENT_MS = 250
}

val sceneTransitions = transitions {
    to(CommunalScenes.Communal, key = CommunalTransitionKeys.SimpleFade) {
        spec = tween(durationMillis = 250)
@@ -97,6 +107,30 @@ val sceneTransitions = transitions {
        }
        timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) }
    }
    to(CommunalScenes.Blank, key = CommunalTransitionKeys.ToEditMode) {
        spec = tween(durationMillis = TransitionDuration.BETWEEN_HUB_AND_EDIT_MODE_MS)
        timestampRange(endMillis = TransitionDuration.HUB_TO_EDIT_MODE_CONTENT_MS) {
            fade(Communal.Elements.Grid)
            fade(Communal.Elements.IndicationArea)
            fade(Communal.Elements.LockIcon)
        }
        fade(Communal.Elements.Scrim)
    }
    to(CommunalScenes.Communal, key = CommunalTransitionKeys.FromEditMode) {
        spec = tween(durationMillis = TransitionDuration.BETWEEN_HUB_AND_EDIT_MODE_MS)
        translate(Communal.Elements.Grid, y = SlideOffsetY)
        timestampRange(endMillis = TransitionDuration.EDIT_MODE_TO_HUB_CONTENT_MS) {
            fade(Communal.Elements.IndicationArea)
            fade(Communal.Elements.LockIcon)
            fade(Communal.Elements.Scrim)
        }
        timestampRange(
            startMillis = TransitionDuration.EDIT_MODE_TO_HUB_GRID_DELAY_MS,
            endMillis = TransitionDuration.EDIT_MODE_TO_HUB_GRID_END_MS
        ) {
            fade(Communal.Elements.Grid)
        }
    }
}

/**
+85 −36
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
@@ -128,6 +130,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Popup
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.window.layout.WindowMetricsCalculator
import com.android.compose.animation.Easings.Emphasized
import com.android.compose.modifiers.thenIf
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
@@ -176,6 +179,10 @@ fun CommunalHub(
        derivedStateOf { selectedKey.value != null || reorderingWidgets }
    }
    val isEmptyState by viewModel.isEmptyState.collectAsStateWithLifecycle(initialValue = false)
    val isCommunalContentVisible by
        viewModel.isCommunalContentVisible.collectAsStateWithLifecycle(
            initialValue = !viewModel.isEditMode
        )

    val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
    val contentOffset = beforeContentPadding(contentPadding).toOffset()
@@ -248,6 +255,30 @@ fun CommunalHub(
                    viewModel = viewModel,
                )
            } else {
                val slideOffsetInPx =
                    with(LocalDensity.current) { Dimensions.SlideOffsetY.toPx().toInt() }
                AnimatedVisibility(
                    visible = isCommunalContentVisible,
                    enter =
                        fadeIn(
                            animationSpec =
                                tween(durationMillis = 83, delayMillis = 83, easing = LinearEasing)
                        ) +
                            slideInVertically(
                                animationSpec = tween(durationMillis = 1000, easing = Emphasized),
                                initialOffsetY = { -slideOffsetInPx }
                            ),
                    exit =
                        fadeOut(
                            animationSpec = tween(durationMillis = 167, easing = LinearEasing)
                        ) +
                            slideOutVertically(
                                animationSpec = tween(durationMillis = 1000, easing = Emphasized),
                                targetOffsetY = { -slideOffsetInPx }
                            ),
                    modifier = Modifier.fillMaxSize(),
                ) {
                    Box {
                        CommunalHubLazyGrid(
                            communalContent = communalContent,
                            viewModel = viewModel,
@@ -257,7 +288,8 @@ fun CommunalHub(
                            updateDragPositionForRemove = { offset ->
                                isPointerWithinEnabledRemoveButton(
                                    removeEnabled = removeButtonEnabled,
                            offset = gridCoordinates?.let { it.positionInWindow() + offset },
                                    offset =
                                        gridCoordinates?.let { it.positionInWindow() + offset },
                                    containerToCheck = removeButtonCoordinates
                                )
                            },
@@ -269,8 +301,23 @@ fun CommunalHub(
                        )
                    }
                }
            }
        }

        if (viewModel.isEditMode && onOpenWidgetPicker != null && onEditDone != null) {
        if (onOpenWidgetPicker != null && onEditDone != null) {
            AnimatedVisibility(
                visible = viewModel.isEditMode && isCommunalContentVisible,
                enter =
                    fadeIn(animationSpec = tween(durationMillis = 250, easing = LinearEasing)) +
                        slideInVertically(
                            animationSpec = tween(durationMillis = 1000, easing = Emphasized),
                        ),
                exit =
                    fadeOut(animationSpec = tween(durationMillis = 167, easing = LinearEasing)) +
                        slideOutVertically(
                            animationSpec = tween(durationMillis = 1000, easing = Emphasized)
                        ),
            ) {
                Toolbar(
                    setToolbarSize = { toolbarSize = it },
                    setRemoveButtonCoordinates = { removeButtonCoordinates = it },
@@ -290,6 +337,7 @@ fun CommunalHub(
                    removeEnabled = removeButtonEnabled
                )
            }
        }
        if (currentPopup == PopupType.CtaTile) {
            PopupOnDismissCtaTile(viewModel::onHidePopup)
        }
@@ -1331,6 +1379,7 @@ object Dimensions {
            horizontal = ToolbarButtonPaddingHorizontal,
        )
    val IconSize = 40.dp
    val SlideOffsetY = 30.dp
}

private object Colors {
+19 −0
Original line number Diff line number Diff line
@@ -111,6 +111,25 @@ class CommunalSceneStartableTest : SysuiTestCase() {
            }
        }

    @Test
    fun keyguardGoesAway_whenInEditMode_doesNotChangeScene() =
        with(kosmos) {
            testScope.runTest {
                val scene by collectLastValue(communalSceneInteractor.currentScene)
                communalSceneInteractor.changeScene(CommunalScenes.Communal)
                assertThat(scene).isEqualTo(CommunalScenes.Communal)

                communalInteractor.setEditModeOpen(true)
                fakeKeyguardTransitionRepository.sendTransitionSteps(
                    from = KeyguardState.ALTERNATE_BOUNCER,
                    to = KeyguardState.GONE,
                    testScope = this
                )
                // Scene change will be handled in EditWidgetsActivity not here
                assertThat(scene).isEqualTo(CommunalScenes.Communal)
            }
        }

    @Ignore("Ignored until custom animations are implemented in b/322787129")
    @Test
    fun deviceDocked_forceCommunalScene() =
+7 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import com.android.systemui.communal.domain.model.CommunalTransitionProgressMode
import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.communal.shared.model.EditModeState
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
@@ -121,6 +122,7 @@ class CommunalInteractorTest : SysuiTestCase() {
    private lateinit var communalPrefsRepository: FakeCommunalPrefsRepository
    private lateinit var editWidgetsActivityStarter: EditWidgetsActivityStarter
    private lateinit var sceneInteractor: SceneInteractor
    private lateinit var communalSceneInteractor: CommunalSceneInteractor
    private lateinit var userTracker: FakeUserTracker
    private lateinit var activityStarter: ActivityStarter
    private lateinit var userManager: UserManager
@@ -141,6 +143,7 @@ class CommunalInteractorTest : SysuiTestCase() {
        editWidgetsActivityStarter = kosmos.editWidgetsActivityStarter
        communalPrefsRepository = kosmos.fakeCommunalPrefsRepository
        sceneInteractor = kosmos.sceneInteractor
        communalSceneInteractor = kosmos.communalSceneInteractor
        userTracker = kosmos.fakeUserTracker
        activityStarter = kosmos.activityStarter
        userManager = kosmos.userManager
@@ -815,7 +818,11 @@ class CommunalInteractorTest : SysuiTestCase() {
    @Test
    fun testShowWidgetEditorStartsActivity() =
        testScope.runTest {
            val editModeState by collectLastValue(communalSceneInteractor.editModeState)

            underTest.showWidgetEditor()

            assertThat(editModeState).isEqualTo(EditModeState.STARTING)
            verify(editWidgetsActivityStarter).startActivity()
        }

+22 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.EditModeState
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
@@ -81,6 +82,27 @@ class CommunalSceneInteractorTest : SysuiTestCase() {
            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
        }

    @Test
    fun snapToSceneForActivity() =
        testScope.runTest {
            val currentScene by collectLastValue(underTest.currentScene)
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)

            underTest.snapToSceneForActivityStart(CommunalScenes.Communal)
            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
        }

    @Test
    fun snapToSceneForActivity_willNotChangeScene_forEditModeActivity() =
        testScope.runTest {
            val currentScene by collectLastValue(underTest.currentScene)
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)

            underTest.setEditModeState(EditModeState.STARTING)
            underTest.snapToSceneForActivityStart(CommunalScenes.Communal)
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
        }

    @Test
    fun transitionProgress_fullProgress() =
        testScope.runTest {
Loading