Loading packages/SystemUI/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -529,6 +529,7 @@ android_library { "Traceur-res", "//frameworks/libs/systemui:motion_tool_lib", "//frameworks/libs/systemui:contextualeducationlib", "//frameworks/libs/systemui/mechanics/compose:mechanics-compose", "notification_flags_lib", "PlatformComposeCore", "PlatformComposeSceneTransitionLayout", Loading Loading @@ -724,6 +725,7 @@ android_library { "LowLightDreamLib", "//frameworks/libs/systemui:motion_tool_lib", "//frameworks/libs/systemui:contextualeducationlib", "//frameworks/libs/systemui/mechanics/compose:mechanics-compose", "androidx.core_core-animation-testing", "androidx.lifecycle_lifecycle-runtime-testing", "androidx.compose.ui_ui", Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt +22 −1 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.util.fastMap import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.mechanics.compose.modifier.verticalTactileSurfaceReveal import com.android.mechanics.spec.builder.rememberMotionBuilderContext import com.android.systemui.dagger.SysUISingleton import com.android.systemui.grid.ui.compose.VerticalSpannedGrid import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider Loading @@ -49,9 +52,10 @@ import com.android.systemui.qs.panels.ui.viewmodel.TextFeedbackContentViewModel import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.ui.ElementKeys.toElementKey import com.android.systemui.qs.ui.composable.QuickSettingsShade import com.android.systemui.res.R import kotlinx.coroutines.launch import javax.inject.Inject import kotlinx.coroutines.launch @SysUISingleton class InfiniteGridLayout Loading Loading @@ -105,6 +109,11 @@ constructor( val scope = rememberCoroutineScope() val spans by remember(sizedTiles) { derivedStateOf { sizedTiles.fastMap { it.width } } } val isDualShade = viewModel.isDualShade val motionBuilderContext = rememberMotionBuilderContext() val marginBottom = with(LocalDensity.current) { QuickSettingsShade.Dimensions.Padding.toPx() } VerticalSpannedGrid( columns = columns, columnSpacing = dimensionResource(R.dimen.qs_tile_margin_horizontal), Loading Loading @@ -134,6 +143,18 @@ constructor( detailsViewModel = detailsViewModel, isVisible = listening, requestToggleTextFeedback = textFeedbackViewModel::requestShowFeedback, modifier = if (isDualShade) { Modifier.verticalTactileSurfaceReveal( contentScope = this@TileGrid, motionBuilderContext = motionBuilderContext, container = QuickSettingsShade.Elements.Panel, deltaY = -marginBottom, ) } else { Modifier }, verticalFadeContentReveal = isDualShade, ) } } Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt +16 −1 Original line number Diff line number Diff line Loading @@ -75,8 +75,11 @@ import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.animation.Expandable import com.android.compose.animation.bounceable import com.android.compose.animation.rememberExpandableController import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.thenIf import com.android.compose.theme.LocalAndroidColorScheme import com.android.mechanics.compose.modifier.verticalFadeContentReveal import com.android.mechanics.spec.builder.rememberMotionBuilderContext import com.android.systemui.Flags import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon Loading @@ -98,6 +101,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.toIconProvider import com.android.systemui.qs.panels.ui.viewmodel.toUiState import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.ui.composable.QuickSettingsShade import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R import kotlinx.coroutines.CoroutineScope Loading Loading @@ -128,7 +132,7 @@ private val TileViewModel.traceName get() = spec.toString().takeLast(Trace.MAX_SECTION_NAME_LEN) @Composable fun Tile( fun ContentScope.Tile( tile: TileViewModel, iconOnly: Boolean, squishiness: () -> Float, Loading @@ -139,6 +143,7 @@ fun Tile( isVisible: () -> Boolean = { true }, requestToggleTextFeedback: (TileSpec) -> Unit = {}, detailsViewModel: DetailsViewModel?, verticalFadeContentReveal: Boolean = false, ) { trace(tile.traceName) { val currentBounceableInfo by rememberUpdatedState(bounceableInfo) Loading Loading @@ -246,6 +251,16 @@ fun Tile( accessibilityUiState = uiState.accessibilityUiState, iconOnly = iconOnly, isDualTarget = isDualTarget, modifier = if (verticalFadeContentReveal) { Modifier.verticalFadeContentReveal( contentScope = this, motionBuilderContext = rememberMotionBuilderContext(), container = QuickSettingsShade.Elements.Panel, ) } else { Modifier }, ) { val iconProvider: Context.() -> Icon = { getTileIcon(icon = icon) } if (iconOnly) { Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt +18 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,12 @@ package com.android.systemui.qs.panels.ui.viewmodel import androidx.compose.runtime.getValue import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator import com.android.systemui.qs.panels.ui.dialog.QSResetDialogDelegate import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.shade.shared.model.ShadeMode import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject Loading @@ -28,9 +33,21 @@ constructor( val squishinessViewModel: TileSquishinessViewModel, val snapshotViewModelFactory: InfiniteGridSnapshotViewModel.Factory, val resetDialogDelegateFactory: QSResetDialogDelegate.Factory, ) { val shadeModeInteractor: ShadeModeInteractor, ) : ExclusiveActivatable() { private val hydrator = Hydrator("InfiniteGridViewModel.hydrator") @AssistedFactory interface Factory { fun create(): InfiniteGridViewModel } private val shadeMode by hydrator.hydratedStateOf("shadeMode", shadeModeInteractor.shadeMode) val isDualShade: Boolean get() = shadeMode == ShadeMode.Dual override suspend fun onActivated(): Nothing { hydrator.activate() } } packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/TileBounceMotionTest.kt +29 −21 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ import androidx.compose.ui.test.hasText import androidx.compose.ui.unit.dp import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.TestScenes.SceneA import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState import com.android.compose.theme.PlatformTheme import com.android.systemui.SysuiTestCase import com.android.systemui.grid.ui.compose.VerticalSpannedGrid Loading Loading @@ -73,6 +76,8 @@ class TileBounceMotionTest : SysuiTestCase() { val bounceables = remember { List(tiles.size) { BounceableTileViewModel() } } val spans = remember { tiles.map { it.span } } PlatformTheme { SceneTransitionLayout(rememberMutableSceneTransitionLayoutState(SceneA)) { scene(SceneA) { VerticalSpannedGrid( columns = 4, columnSpacing = 8.dp, Loading @@ -91,11 +96,14 @@ class TileBounceMotionTest : SysuiTestCase() { nextTile = bounceables.getOrNull(index + 1), bounceEnd = index != tiles.size - 1, ), tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider, tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider, detailsViewModel = null, ) } } } } LaunchedEffect(play) { if (play) { Loading Loading
packages/SystemUI/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -529,6 +529,7 @@ android_library { "Traceur-res", "//frameworks/libs/systemui:motion_tool_lib", "//frameworks/libs/systemui:contextualeducationlib", "//frameworks/libs/systemui/mechanics/compose:mechanics-compose", "notification_flags_lib", "PlatformComposeCore", "PlatformComposeSceneTransitionLayout", Loading Loading @@ -724,6 +725,7 @@ android_library { "LowLightDreamLib", "//frameworks/libs/systemui:motion_tool_lib", "//frameworks/libs/systemui:contextualeducationlib", "//frameworks/libs/systemui/mechanics/compose:mechanics-compose", "androidx.core_core-animation-testing", "androidx.lifecycle_lifecycle-runtime-testing", "androidx.compose.ui_ui", Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt +22 −1 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.util.fastMap import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.mechanics.compose.modifier.verticalTactileSurfaceReveal import com.android.mechanics.spec.builder.rememberMotionBuilderContext import com.android.systemui.dagger.SysUISingleton import com.android.systemui.grid.ui.compose.VerticalSpannedGrid import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider Loading @@ -49,9 +52,10 @@ import com.android.systemui.qs.panels.ui.viewmodel.TextFeedbackContentViewModel import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.ui.ElementKeys.toElementKey import com.android.systemui.qs.ui.composable.QuickSettingsShade import com.android.systemui.res.R import kotlinx.coroutines.launch import javax.inject.Inject import kotlinx.coroutines.launch @SysUISingleton class InfiniteGridLayout Loading Loading @@ -105,6 +109,11 @@ constructor( val scope = rememberCoroutineScope() val spans by remember(sizedTiles) { derivedStateOf { sizedTiles.fastMap { it.width } } } val isDualShade = viewModel.isDualShade val motionBuilderContext = rememberMotionBuilderContext() val marginBottom = with(LocalDensity.current) { QuickSettingsShade.Dimensions.Padding.toPx() } VerticalSpannedGrid( columns = columns, columnSpacing = dimensionResource(R.dimen.qs_tile_margin_horizontal), Loading Loading @@ -134,6 +143,18 @@ constructor( detailsViewModel = detailsViewModel, isVisible = listening, requestToggleTextFeedback = textFeedbackViewModel::requestShowFeedback, modifier = if (isDualShade) { Modifier.verticalTactileSurfaceReveal( contentScope = this@TileGrid, motionBuilderContext = motionBuilderContext, container = QuickSettingsShade.Elements.Panel, deltaY = -marginBottom, ) } else { Modifier }, verticalFadeContentReveal = isDualShade, ) } } Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt +16 −1 Original line number Diff line number Diff line Loading @@ -75,8 +75,11 @@ import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.animation.Expandable import com.android.compose.animation.bounceable import com.android.compose.animation.rememberExpandableController import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.thenIf import com.android.compose.theme.LocalAndroidColorScheme import com.android.mechanics.compose.modifier.verticalFadeContentReveal import com.android.mechanics.spec.builder.rememberMotionBuilderContext import com.android.systemui.Flags import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon Loading @@ -98,6 +101,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.toIconProvider import com.android.systemui.qs.panels.ui.viewmodel.toUiState import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.ui.composable.QuickSettingsShade import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R import kotlinx.coroutines.CoroutineScope Loading Loading @@ -128,7 +132,7 @@ private val TileViewModel.traceName get() = spec.toString().takeLast(Trace.MAX_SECTION_NAME_LEN) @Composable fun Tile( fun ContentScope.Tile( tile: TileViewModel, iconOnly: Boolean, squishiness: () -> Float, Loading @@ -139,6 +143,7 @@ fun Tile( isVisible: () -> Boolean = { true }, requestToggleTextFeedback: (TileSpec) -> Unit = {}, detailsViewModel: DetailsViewModel?, verticalFadeContentReveal: Boolean = false, ) { trace(tile.traceName) { val currentBounceableInfo by rememberUpdatedState(bounceableInfo) Loading Loading @@ -246,6 +251,16 @@ fun Tile( accessibilityUiState = uiState.accessibilityUiState, iconOnly = iconOnly, isDualTarget = isDualTarget, modifier = if (verticalFadeContentReveal) { Modifier.verticalFadeContentReveal( contentScope = this, motionBuilderContext = rememberMotionBuilderContext(), container = QuickSettingsShade.Elements.Panel, ) } else { Modifier }, ) { val iconProvider: Context.() -> Icon = { getTileIcon(icon = icon) } if (iconOnly) { Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt +18 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,12 @@ package com.android.systemui.qs.panels.ui.viewmodel import androidx.compose.runtime.getValue import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator import com.android.systemui.qs.panels.ui.dialog.QSResetDialogDelegate import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.shade.shared.model.ShadeMode import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject Loading @@ -28,9 +33,21 @@ constructor( val squishinessViewModel: TileSquishinessViewModel, val snapshotViewModelFactory: InfiniteGridSnapshotViewModel.Factory, val resetDialogDelegateFactory: QSResetDialogDelegate.Factory, ) { val shadeModeInteractor: ShadeModeInteractor, ) : ExclusiveActivatable() { private val hydrator = Hydrator("InfiniteGridViewModel.hydrator") @AssistedFactory interface Factory { fun create(): InfiniteGridViewModel } private val shadeMode by hydrator.hydratedStateOf("shadeMode", shadeModeInteractor.shadeMode) val isDualShade: Boolean get() = shadeMode == ShadeMode.Dual override suspend fun onActivated(): Nothing { hydrator.activate() } }
packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/TileBounceMotionTest.kt +29 −21 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ import androidx.compose.ui.test.hasText import androidx.compose.ui.unit.dp import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.TestScenes.SceneA import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState import com.android.compose.theme.PlatformTheme import com.android.systemui.SysuiTestCase import com.android.systemui.grid.ui.compose.VerticalSpannedGrid Loading Loading @@ -73,6 +76,8 @@ class TileBounceMotionTest : SysuiTestCase() { val bounceables = remember { List(tiles.size) { BounceableTileViewModel() } } val spans = remember { tiles.map { it.span } } PlatformTheme { SceneTransitionLayout(rememberMutableSceneTransitionLayoutState(SceneA)) { scene(SceneA) { VerticalSpannedGrid( columns = 4, columnSpacing = 8.dp, Loading @@ -91,11 +96,14 @@ class TileBounceMotionTest : SysuiTestCase() { nextTile = bounceables.getOrNull(index + 1), bounceEnd = index != tiles.size - 1, ), tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider, tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider, detailsViewModel = null, ) } } } } LaunchedEffect(play) { if (play) { Loading