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

Commit f20ce5dc authored by Sherry Zhou's avatar Sherry Zhou
Browse files

Use SceneTransitionLayout for weather clock

Flag: ACONFIG com.android.systemui.compose_lockscreen DEVELOPMENT
Bug: 329306210
Test: manual
Change-Id: I5283d1c1b86b65fc145c90c4604769f9c309786d
parent a6c4eca0
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ package com.android.systemui.keyguard.ui.composable
import com.android.systemui.keyguard.ui.composable.blueprint.CommunalBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.DefaultBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.ShortcutsBesideUdfpsBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.SplitShadeWeatherClockBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.WeatherClockBlueprintModule
import com.android.systemui.keyguard.ui.composable.section.OptionalSectionModule
import dagger.Module

@@ -31,8 +29,6 @@ import dagger.Module
            DefaultBlueprintModule::class,
            OptionalSectionModule::class,
            ShortcutsBesideUdfpsBlueprintModule::class,
            SplitShadeWeatherClockBlueprintModule::class,
            WeatherClockBlueprintModule::class,
        ],
)
interface LockscreenSceneBlueprintModule
+40 −8
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@ import com.android.compose.animation.scene.transitions
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.largeClockElementKey
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smallClockElementKey
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smartspaceElementKey
import com.android.systemui.keyguard.ui.composable.blueprint.ClockTransition.transitioningToLargeClock
import com.android.systemui.keyguard.ui.composable.blueprint.ClockTransition.transitioningToSmallClock
import com.android.systemui.keyguard.ui.composable.blueprint.WeatherClockElementKeys.largeWeatherClockElementKeyList
import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.ClockFaceInTransition.Companion.CLOCK_IN_MILLIS
import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.ClockFaceInTransition.Companion.CLOCK_IN_START_DELAY_MILLIS
import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.ClockFaceOutTransition.Companion.CLOCK_OUT_MILLIS
@@ -34,30 +37,45 @@ import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSi
object ClockTransition {
    val defaultClockTransitions = transitions {
        from(ClockScenes.smallClockScene, to = ClockScenes.largeClockScene) {
            transitioningToLargeClock()
            transitioningToLargeClock(largeClockElements = listOf(largeClockElementKey))
        }
        from(ClockScenes.largeClockScene, to = ClockScenes.smallClockScene) {
            transitioningToSmallClock()
            transitioningToSmallClock(largeClockElements = listOf(largeClockElementKey))
        }
        from(ClockScenes.splitShadeLargeClockScene, to = ClockScenes.largeClockScene) {
            spec = tween(1000, easing = LinearEasing)
            spec = tween(300, easing = LinearEasing)
        }

        from(WeatherClockScenes.largeClockScene, to = ClockScenes.smallClockScene) {
            transitioningToSmallClock(largeClockElements = largeWeatherClockElementKeyList)
        }

        from(ClockScenes.smallClockScene, to = WeatherClockScenes.largeClockScene) {
            transitioningToLargeClock(largeClockElements = largeWeatherClockElementKeyList)
        }

        from(
            WeatherClockScenes.largeClockScene,
            to = WeatherClockScenes.splitShadeLargeClockScene
        ) {
            spec = tween(300, easing = LinearEasing)
        }
    }

    private fun TransitionBuilder.transitioningToLargeClock() {
    private fun TransitionBuilder.transitioningToLargeClock(largeClockElements: List<ElementKey>) {
        spec = tween(durationMillis = STATUS_AREA_MOVE_UP_MILLIS.toInt())
        timestampRange(
            startMillis = CLOCK_IN_START_DELAY_MILLIS.toInt(),
            endMillis = (CLOCK_IN_START_DELAY_MILLIS + CLOCK_IN_MILLIS).toInt()
        ) {
            fade(largeClockElementKey)
            largeClockElements.forEach { fade(it) }
        }

        timestampRange(endMillis = CLOCK_OUT_MILLIS.toInt()) { fade(smallClockElementKey) }
        anchoredTranslate(smallClockElementKey, smartspaceElementKey)
    }

    private fun TransitionBuilder.transitioningToSmallClock() {
    private fun TransitionBuilder.transitioningToSmallClock(largeClockElements: List<ElementKey>) {
        spec = tween(durationMillis = STATUS_AREA_MOVE_DOWN_MILLIS.toInt())
        timestampRange(
            startMillis = CLOCK_IN_START_DELAY_MILLIS.toInt(),
@@ -66,7 +84,9 @@ object ClockTransition {
            fade(smallClockElementKey)
        }

        timestampRange(endMillis = CLOCK_OUT_MILLIS.toInt()) { fade(largeClockElementKey) }
        timestampRange(endMillis = CLOCK_OUT_MILLIS.toInt()) {
            largeClockElements.forEach { fade(it) }
        }
        anchoredTranslate(smallClockElementKey, smartspaceElementKey)
    }
}
@@ -81,14 +101,26 @@ object ClockScenes {
object ClockElementKeys {
    val largeClockElementKey = ElementKey("large-clock")
    val smallClockElementKey = ElementKey("small-clock")
    val weatherSmallClockElementKey = ElementKey("weather-small-clock")
    val smartspaceElementKey = ElementKey("smart-space")
}

object WeatherClockScenes {
    val largeClockScene = SceneKey("large-weather-clock-scene")
    val splitShadeLargeClockScene = SceneKey("split-shade-large-weather-clock-scene")
}

object WeatherClockElementKeys {
    val timeElementKey = ElementKey("weather-large-clock-time")
    val dateElementKey = ElementKey("weather-large-clock-date")
    val weatherIconElementKey = ElementKey("weather-large-clock-weather-icon")
    val temperatureElementKey = ElementKey("weather-large-clock-temperature")
    val dndAlarmElementKey = ElementKey("weather-large-clock-dnd-alarm")
    val largeWeatherClockElementKeyList =
        listOf(
            timeElementKey,
            dateElementKey,
            weatherIconElementKey,
            temperatureElementKey,
            dndAlarmElementKey
        )
}
+0 −499

File deleted.

Preview size limit exceeded, changes collapsed.

+64 −0
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.systemui.keyguard.ui.composable.section

import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.Composable
@@ -26,6 +28,10 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.SceneTransitionLayout
@@ -36,6 +42,7 @@ import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.smallCl
import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.splitShadeLargeClockScene
import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.splitShadeSmallClockScene
import com.android.systemui.keyguard.ui.composable.blueprint.ClockTransition
import com.android.systemui.keyguard.ui.composable.blueprint.WeatherClockScenes
import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import javax.inject.Inject
@@ -47,6 +54,7 @@ constructor(
    private val smartSpaceSection: SmartSpaceSection,
    private val mediaCarouselSection: MediaCarouselSection,
    private val clockSection: DefaultClockSection,
    private val weatherClockSection: WeatherClockSection,
    private val clockInteractor: KeyguardClockInteractor,
) {
    @Composable
@@ -64,6 +72,10 @@ constructor(
                    splitShadeSmallClockScene
                KeyguardClockViewModel.ClockLayout.LARGE_CLOCK -> largeClockScene
                KeyguardClockViewModel.ClockLayout.SMALL_CLOCK -> smallClockScene
                KeyguardClockViewModel.ClockLayout.WEATHER_LARGE_CLOCK ->
                    WeatherClockScenes.largeClockScene
                KeyguardClockViewModel.ClockLayout.SPLIT_SHADE_WEATHER_LARGE_CLOCK ->
                    WeatherClockScenes.splitShadeLargeClockScene
            }

        SceneTransitionLayout(
@@ -86,6 +98,12 @@ constructor(
            scene(smallClockScene) { SmallClockWithSmartSpace() }

            scene(largeClockScene) { LargeClockWithSmartSpace() }

            scene(WeatherClockScenes.largeClockScene) { WeatherLargeClockWithSmartSpace() }

            scene(WeatherClockScenes.splitShadeLargeClockScene) {
                WeatherLargeClockWithSmartSpace(modifier = Modifier.fillMaxWidth(0.5f))
            }
        }
    }

@@ -146,4 +164,50 @@ constructor(
            }
        }
    }

    @Composable
    private fun SceneScope.WeatherLargeClockWithSmartSpace(modifier: Modifier = Modifier) {
        val burnIn = rememberBurnIn(clockInteractor)
        val isLargeClockVisible by clockViewModel.isLargeClockVisible.collectAsState()
        val currentClockState = clockViewModel.currentClock.collectAsState()

        LaunchedEffect(isLargeClockVisible) {
            if (isLargeClockVisible) {
                burnIn.onSmallClockTopChanged(null)
            }
        }

        Column(modifier = modifier) {
            val currentClock = currentClockState.value ?: return@Column
            with(weatherClockSection) { Time(clock = currentClock, modifier = Modifier) }
            val density = LocalDensity.current
            val context = LocalContext.current

            with(smartSpaceSection) {
                SmartSpace(
                    burnInParams = burnIn.parameters,
                    onTopChanged = burnIn.onSmartspaceTopChanged,
                    modifier =
                        Modifier.heightIn(
                            min = getDimen(context, "enhanced_smartspace_height", density)
                        )
                )
            }
            with(weatherClockSection) { LargeClockSectionBelowSmartspace(clock = currentClock) }
        }
    }

    /*
     * Use this function to access dimen which cannot be access by R.dimen directly
     * Currently use to access dimen from BcSmartspace
     * @param name Name of resources
     * @param density Density required to convert dimen from Int To Dp
     */
    private fun getDimen(context: Context, name: String, density: Density): Dp {
        val res = context.packageManager.getResourcesForApplication(context.packageName)
        val id = res.getIdentifier(name, "dimen", context.packageName)
        var dimen: Dp
        with(density) { dimen = (if (id == 0) 0 else res.getDimensionPixelSize(id)).toDp() }
        return dimen
    }
}
+39 −55
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.keyguard.ui.composable.section

import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.IntrinsicSize
@@ -27,18 +28,14 @@ import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.padding
import com.android.systemui.customization.R
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.weatherSmallClockElementKey
import com.android.systemui.customization.R as customizationR
import com.android.systemui.keyguard.ui.composable.blueprint.WeatherClockElementKeys
import com.android.systemui.keyguard.ui.composable.modifier.burnInAware
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import com.android.systemui.plugins.clocks.ClockController
import javax.inject.Inject
@@ -54,14 +51,21 @@ constructor(
    fun SceneScope.Time(
        clock: ClockController,
        modifier: Modifier = Modifier,
    ) {
        Row(
            modifier =
                Modifier.padding(
                    horizontal = dimensionResource(customizationR.dimen.clock_padding_start)
                )
        ) {
            WeatherElement(
            weatherClockElementViewId = R.id.weather_clock_time,
                weatherClockElementViewId = customizationR.id.weather_clock_time,
                clock = clock,
                elementKey = WeatherClockElementKeys.timeElementKey,
            modifier = modifier.wrapContentSize(),
                modifier = modifier,
            )
        }
    }

    @Composable
    private fun SceneScope.Date(
@@ -69,7 +73,7 @@ constructor(
        modifier: Modifier = Modifier,
    ) {
        WeatherElement(
            weatherClockElementViewId = R.id.weather_clock_date,
            weatherClockElementViewId = customizationR.id.weather_clock_date,
            clock = clock,
            elementKey = WeatherClockElementKeys.dateElementKey,
            modifier = modifier,
@@ -82,7 +86,7 @@ constructor(
        modifier: Modifier = Modifier,
    ) {
        WeatherElement(
            weatherClockElementViewId = R.id.weather_clock_weather_icon,
            weatherClockElementViewId = customizationR.id.weather_clock_weather_icon,
            clock = clock,
            elementKey = WeatherClockElementKeys.weatherIconElementKey,
            modifier = modifier.wrapContentSize(),
@@ -95,7 +99,7 @@ constructor(
        modifier: Modifier = Modifier,
    ) {
        WeatherElement(
            weatherClockElementViewId = R.id.weather_clock_alarm_dnd,
            weatherClockElementViewId = customizationR.id.weather_clock_alarm_dnd,
            clock = clock,
            elementKey = WeatherClockElementKeys.dndAlarmElementKey,
            modifier = modifier.wrapContentSize(),
@@ -108,7 +112,7 @@ constructor(
        modifier: Modifier = Modifier,
    ) {
        WeatherElement(
            weatherClockElementViewId = R.id.weather_clock_temperature,
            weatherClockElementViewId = customizationR.id.weather_clock_temperature,
            clock = clock,
            elementKey = WeatherClockElementKeys.temperatureElementKey,
            modifier = modifier.wrapContentSize(),
@@ -126,12 +130,16 @@ constructor(
            content {
                AndroidView(
                    factory = {
                        try {
                            val view =
                                clock.largeClock.layout.views.first {
                                    it.id == weatherClockElementViewId
                                }
                            (view.parent as? ViewGroup)?.removeView(view)
                            view
                        } catch (e: NoSuchElementException) {
                            View(it)
                        }
                    },
                    update = {},
                    modifier = modifier
@@ -147,46 +155,22 @@ constructor(
        Row(
            modifier =
                Modifier.height(IntrinsicSize.Max)
                    .padding(horizontal = dimensionResource(R.dimen.clock_padding_start))
                    .padding(
                        horizontal = dimensionResource(customizationR.dimen.clock_padding_start)
                    )
        ) {
            Date(clock = clock, modifier = Modifier.wrapContentSize())
            Box(modifier = Modifier.fillMaxSize()) {
            Box(
                modifier =
                    Modifier.fillMaxSize()
                        .padding(
                            start = dimensionResource(customizationR.dimen.clock_padding_start)
                        )
            ) {
                Weather(clock = clock, modifier = Modifier.align(Alignment.TopStart))
                Temperature(clock = clock, modifier = Modifier.align(Alignment.BottomEnd))
                DndAlarmStatus(clock = clock, modifier = Modifier.align(Alignment.TopEnd))
            }
        }
    }

    @Composable
    fun SceneScope.SmallClock(
        burnInParams: BurnInParameters,
        modifier: Modifier = Modifier,
        clock: ClockController,
    ) {
        val localContext = LocalContext.current
        MovableElement(key = weatherSmallClockElementKey, modifier) {
            content {
                AndroidView(
                    factory = {
                        val view = clock.smallClock.view
                        if (view.parent != null) {
                            (view.parent as? ViewGroup)?.removeView(view)
                        }
                        view
                    },
                    modifier =
                        modifier
                            .height(dimensionResource(R.dimen.small_clock_height))
                            .padding(start = dimensionResource(R.dimen.clock_padding_start))
                            .padding(top = { viewModel.getSmallClockTopMargin(localContext) })
                            .burnInAware(
                                viewModel = aodBurnInViewModel,
                                params = burnInParams,
                            ),
                    update = {},
                )
            }
        }
    }
}
Loading