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

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

Merge changes I06425379,Ifa2afa17 into main

* changes:
  Polish hub <-> lockscreen motion
  Implement dream overlay motion when entering hub
parents c7585718 4a00ae2e
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -22,12 +22,15 @@ import android.view.View
import android.view.WindowInsets
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleOwner
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.compose.theme.PlatformTheme
import com.android.compose.ui.platform.DensityAwareComposeView
import com.android.internal.policy.ScreenDecorationsUtils
@@ -89,6 +92,11 @@ object ComposeFacade : BaseComposeFacade {
    ) {
        activity.setContent {
            PlatformTheme {
                Box(
                    modifier =
                        Modifier.fillMaxSize()
                            .background(LocalAndroidColorScheme.current.outlineVariant),
                ) {
                    CommunalHub(
                        viewModel = viewModel,
                        onOpenWidgetPicker = onOpenWidgetPicker,
@@ -98,6 +106,7 @@ object ComposeFacade : BaseComposeFacade {
                }
            }
        }
    }

    override fun setVolumePanelActivityContent(
        activity: ComponentActivity,
+22 −4
Original line number Diff line number Diff line
package com.android.systemui.communal.ui.compose

import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
@@ -12,6 +13,7 @@ import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.FixedSizeEdgeDetector
import com.android.compose.animation.scene.LowestZIndexScenePicker
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneScope
@@ -21,6 +23,7 @@ import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
import com.android.compose.animation.scene.updateSceneTransitionLayoutState
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.communal.shared.model.ObservableCommunalTransitionState
import com.android.systemui.communal.ui.compose.extensions.allowGestures
@@ -31,18 +34,27 @@ import kotlinx.coroutines.flow.transform

object Communal {
    object Elements {
        val Scrim = ElementKey("Scrim", scenePicker = LowestZIndexScenePicker)
        val Content = ElementKey("CommunalContent")
    }
}

val sceneTransitions = transitions {
    from(TransitionSceneKey.Blank, to = TransitionSceneKey.Communal) {
        spec = tween(durationMillis = 500)

    to(TransitionSceneKey.Communal) {
        spec = tween(durationMillis = 1000)
        translate(Communal.Elements.Content, Edge.Right)
        timestampRange(startMillis = 167, endMillis = 334) {
            fade(Communal.Elements.Scrim)
            fade(Communal.Elements.Content)
        }
    }
    to(TransitionSceneKey.Blank) {
        spec = tween(durationMillis = 1000)
        translate(Communal.Elements.Content, Edge.Right)
        timestampRange(endMillis = 167) { fade(Communal.Elements.Content) }
        timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) }
    }
}

/**
 * View containing a [SceneTransitionLayout] that shows the communal UI and handles transitions.
@@ -111,6 +123,12 @@ private fun SceneScope.CommunalScene(
    viewModel: BaseCommunalViewModel,
    modifier: Modifier = Modifier,
) {
    Box(
        modifier =
            Modifier.element(Communal.Elements.Scrim)
                .fillMaxSize()
                .background(LocalAndroidColorScheme.current.outlineVariant),
    )
    Box(modifier.element(Communal.Elements.Content)) { CommunalHub(viewModel = viewModel) }
}

+0 −1
Original line number Diff line number Diff line
@@ -141,7 +141,6 @@ fun CommunalHub(
        modifier =
            modifier
                .fillMaxSize()
                .background(LocalAndroidColorScheme.current.outlineVariant)
                .pointerInput(gridState, contentOffset, contentListState) {
                    // If not in edit mode, don't allow selecting items.
                    if (!viewModel.isEditMode) return@pointerInput
+2 −2
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.complication.ComplicationHostViewController
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
import com.android.systemui.dreams.ui.viewmodel.DreamOverlayViewModel
import com.android.systemui.log.core.FakeLogBuffer
import com.android.systemui.statusbar.BlurUtils
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -47,7 +47,7 @@ class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
    @Mock private lateinit var statusBarViewController: DreamOverlayStatusBarViewController
    @Mock private lateinit var stateController: DreamOverlayStateController
    @Mock private lateinit var configController: ConfigurationController
    @Mock private lateinit var transitionViewModel: DreamingToLockscreenTransitionViewModel
    @Mock private lateinit var transitionViewModel: DreamOverlayViewModel
    private val logBuffer = FakeLogBuffer.Factory.create()
    private lateinit var controller: DreamOverlayAnimationsController

+97 −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.keyguard.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class DreamingToGlanceableHubTransitionViewModelTest : SysuiTestCase() {
    val kosmos = testKosmos()
    val testScope = kosmos.testScope

    val underTest by lazy { kosmos.dreamingToGlanceableHubTransitionViewModel }

    @Test
    fun dreamOverlayAlpha() =
        testScope.runTest {
            val values by collectValues(underTest.dreamOverlayAlpha)
            assertThat(values).isEmpty()

            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    // Should start running here...
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.5f),
                    // Up to here...
                    step(1f),
                ),
                testScope,
            )

            assertThat(values).hasSize(4)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
        }

    @Test
    fun dreamOverlayTranslationX() =
        testScope.runTest {
            val values by collectValues(underTest.dreamOverlayTranslationX(100))
            assertThat(values).isEmpty()

            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0.3f),
                    step(0.6f),
                ),
                testScope,
            )

            assertThat(values).hasSize(3)
            values.forEach { assertThat(it).isIn(Range.closed(-100f, 0f)) }
        }

    private fun step(
        value: Float,
        state: TransitionState = TransitionState.RUNNING
    ): TransitionStep {
        return TransitionStep(
            from = KeyguardState.DREAMING,
            to = KeyguardState.GLANCEABLE_HUB,
            value = value,
            transitionState = state,
            ownerName = "DreamingToGlanceableHubTransitionViewModelTest"
        )
    }
}
Loading