Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt +4 −0 Original line number Diff line number Diff line Loading @@ -62,8 +62,12 @@ class EditTileListState( initialTiles.toGridCells(initialLargeTiles).toMutableStateList() val tiles: List<GridCell> = _tiles var largeTilesSpecs: Set<TileSpec> = initialLargeTiles private set /** Update the grid with this new list of tiles and new set of large tileSpecs. */ fun updateTiles(tiles: List<EditTileViewModel>, largeTiles: Set<TileSpec>) { largeTilesSpecs = largeTiles tiles.toGridCells(largeTiles).let { _tiles.apply { clear() Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt +8 −7 Original line number Diff line number Diff line Loading @@ -180,7 +180,6 @@ import kotlin.math.abs import kotlin.math.roundToInt import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map Loading Loading @@ -573,10 +572,14 @@ private fun CurrentTilesGrid( currentListState.resizeTile(resizingOperation.spec, resizingOperation.toIcon) } is FinalResizeOperation -> { // Commit the new size of the tile onEditAction( EditAction.ResizeTile(resizingOperation.spec, resizingOperation.toIcon) ) with(resizingOperation) { // Commit the new size of the tile IF the size changed. Do this check before // a snapshot is taken to avoid saving an unnecessary snapshot val isIcon = spec !in listState.largeTilesSpecs if (isIcon != toIcon) { onEditAction(EditAction.ResizeTile(spec, toIcon)) } } } } } Loading Loading @@ -789,11 +792,9 @@ private fun TileGridCell( // the tile's size LaunchedEffect(resizingState) { snapshotFlow { resizingState.temporaryResizeOperation } .drop(1) // Drop the initial state .onEach { onResize(it) } .launchIn(this) snapshotFlow { resizingState.finalResizeOperation } .drop(1) // Drop the initial state .onEach { onResize(it) } .launchIn(this) } Loading packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt +65 −9 Original line number Diff line number Diff line Loading @@ -61,8 +61,13 @@ class ResizingTest : SysuiTestCase() { private val snapshotViewModelFactory = kosmos.infiniteGridSnapshotViewModelFactory @Composable private fun EditTileGridUnderTest(listState: EditTileListState) { val largeTilesSpecs = TestLargeTilesSpecs.toMutableSet() private fun EditTileGridUnderTest( listState: EditTileListState, tiles: List<EditTileViewModel> = TestEditTiles, largeTiles: Set<TileSpec> = TestLargeTilesSpecs, onResize: (EditAction.ResizeTile) -> Unit = {}, ) { val largeTilesSpecs = remember { largeTiles.toMutableSet() } PlatformTheme { DefaultEditTileGrid( listState = listState, Loading @@ -73,9 +78,11 @@ class ResizingTest : SysuiTestCase() { ) { action -> when (action) { is EditAction.ResizeTile -> { onResize(action) if (action.toIcon) largeTilesSpecs.remove(action.tileSpec) else largeTilesSpecs.add(action.tileSpec) listState.updateTiles(TestEditTiles, largeTilesSpecs) listState.updateTiles(tiles, largeTilesSpecs) } else -> {} } Loading @@ -87,7 +94,8 @@ class ResizingTest : SysuiTestCase() { fun toggleIconTileWithA11yAction_shouldBeLarge() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -97,13 +105,16 @@ class ResizingTest : SysuiTestCase() { ) assertTileHasWidth(listState.tiles, "tileA", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[0].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } @Test fun toggleLargeTileWithA11yAction_shouldBeIcon() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -113,13 +124,16 @@ class ResizingTest : SysuiTestCase() { ) assertTileHasWidth(listState.tiles, "tileD_large", 1) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isTrue() } @Test fun tapOnIconResizingHandle_shouldBeLarge() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -131,13 +145,16 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileA", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[0].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } @Test fun tapOnLargeResizingHandle_shouldBeIcon() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -149,13 +166,16 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileD_large", 1) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isTrue() } @Test fun resizedIcon_shouldBeLarge() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -167,13 +187,16 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileA", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[0].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } @Test fun resizedLarge_shouldBeIcon() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -185,6 +208,39 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileD_large", 1) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isTrue() } @Test fun resizedIconFromEdge_shouldBeLarge() { val testTiles = listOf( createEditTile("tileA"), createEditTile("tileB"), createEditTile("tileC"), createEditTile("tileD"), ) val listState = EditTileListState(testTiles, emptySet(), columns = 4, largeTilesSpan = 2) var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState, testTiles) { resizedAction = it } } composeRule.waitForIdle() composeRule .onNodeWithContentDescription("tileD") .performClick() // Select .performTouchInput { // Tap on resizing handle click(centerRight) } composeRule.waitForIdle() // Assert that tileD was resized to large assertTileHasWidth(listState.tiles, "tileD", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(testTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } private fun assertTileHasWidth(tiles: List<GridCell>, spec: String, expectedWidth: Int) { Loading Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt +4 −0 Original line number Diff line number Diff line Loading @@ -62,8 +62,12 @@ class EditTileListState( initialTiles.toGridCells(initialLargeTiles).toMutableStateList() val tiles: List<GridCell> = _tiles var largeTilesSpecs: Set<TileSpec> = initialLargeTiles private set /** Update the grid with this new list of tiles and new set of large tileSpecs. */ fun updateTiles(tiles: List<EditTileViewModel>, largeTiles: Set<TileSpec>) { largeTilesSpecs = largeTiles tiles.toGridCells(largeTiles).let { _tiles.apply { clear() Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt +8 −7 Original line number Diff line number Diff line Loading @@ -180,7 +180,6 @@ import kotlin.math.abs import kotlin.math.roundToInt import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map Loading Loading @@ -573,10 +572,14 @@ private fun CurrentTilesGrid( currentListState.resizeTile(resizingOperation.spec, resizingOperation.toIcon) } is FinalResizeOperation -> { // Commit the new size of the tile onEditAction( EditAction.ResizeTile(resizingOperation.spec, resizingOperation.toIcon) ) with(resizingOperation) { // Commit the new size of the tile IF the size changed. Do this check before // a snapshot is taken to avoid saving an unnecessary snapshot val isIcon = spec !in listState.largeTilesSpecs if (isIcon != toIcon) { onEditAction(EditAction.ResizeTile(spec, toIcon)) } } } } } Loading Loading @@ -789,11 +792,9 @@ private fun TileGridCell( // the tile's size LaunchedEffect(resizingState) { snapshotFlow { resizingState.temporaryResizeOperation } .drop(1) // Drop the initial state .onEach { onResize(it) } .launchIn(this) snapshotFlow { resizingState.finalResizeOperation } .drop(1) // Drop the initial state .onEach { onResize(it) } .launchIn(this) } Loading
packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt +65 −9 Original line number Diff line number Diff line Loading @@ -61,8 +61,13 @@ class ResizingTest : SysuiTestCase() { private val snapshotViewModelFactory = kosmos.infiniteGridSnapshotViewModelFactory @Composable private fun EditTileGridUnderTest(listState: EditTileListState) { val largeTilesSpecs = TestLargeTilesSpecs.toMutableSet() private fun EditTileGridUnderTest( listState: EditTileListState, tiles: List<EditTileViewModel> = TestEditTiles, largeTiles: Set<TileSpec> = TestLargeTilesSpecs, onResize: (EditAction.ResizeTile) -> Unit = {}, ) { val largeTilesSpecs = remember { largeTiles.toMutableSet() } PlatformTheme { DefaultEditTileGrid( listState = listState, Loading @@ -73,9 +78,11 @@ class ResizingTest : SysuiTestCase() { ) { action -> when (action) { is EditAction.ResizeTile -> { onResize(action) if (action.toIcon) largeTilesSpecs.remove(action.tileSpec) else largeTilesSpecs.add(action.tileSpec) listState.updateTiles(TestEditTiles, largeTilesSpecs) listState.updateTiles(tiles, largeTilesSpecs) } else -> {} } Loading @@ -87,7 +94,8 @@ class ResizingTest : SysuiTestCase() { fun toggleIconTileWithA11yAction_shouldBeLarge() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -97,13 +105,16 @@ class ResizingTest : SysuiTestCase() { ) assertTileHasWidth(listState.tiles, "tileA", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[0].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } @Test fun toggleLargeTileWithA11yAction_shouldBeIcon() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -113,13 +124,16 @@ class ResizingTest : SysuiTestCase() { ) assertTileHasWidth(listState.tiles, "tileD_large", 1) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isTrue() } @Test fun tapOnIconResizingHandle_shouldBeLarge() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -131,13 +145,16 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileA", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[0].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } @Test fun tapOnLargeResizingHandle_shouldBeIcon() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -149,13 +166,16 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileD_large", 1) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isTrue() } @Test fun resizedIcon_shouldBeLarge() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -167,13 +187,16 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileA", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[0].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } @Test fun resizedLarge_shouldBeIcon() { val listState = EditTileListState(TestEditTiles, TestLargeTilesSpecs, columns = 4, largeTilesSpan = 2) composeRule.setContent { EditTileGridUnderTest(listState) } var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState) { resizedAction = it } } composeRule.waitForIdle() composeRule Loading @@ -185,6 +208,39 @@ class ResizingTest : SysuiTestCase() { composeRule.waitForIdle() assertTileHasWidth(listState.tiles, "tileD_large", 1) assertThat(resizedAction!!.tileSpec).isEqualTo(TestEditTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isTrue() } @Test fun resizedIconFromEdge_shouldBeLarge() { val testTiles = listOf( createEditTile("tileA"), createEditTile("tileB"), createEditTile("tileC"), createEditTile("tileD"), ) val listState = EditTileListState(testTiles, emptySet(), columns = 4, largeTilesSpan = 2) var resizedAction: EditAction.ResizeTile? = null composeRule.setContent { EditTileGridUnderTest(listState, testTiles) { resizedAction = it } } composeRule.waitForIdle() composeRule .onNodeWithContentDescription("tileD") .performClick() // Select .performTouchInput { // Tap on resizing handle click(centerRight) } composeRule.waitForIdle() // Assert that tileD was resized to large assertTileHasWidth(listState.tiles, "tileD", 2) assertThat(resizedAction!!.tileSpec).isEqualTo(testTiles[3].tileSpec) assertThat(resizedAction!!.toIcon).isFalse() } private fun assertTileHasWidth(tiles: List<GridCell>, spec: String, expectedWidth: Int) { Loading