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

Commit cbd80fad authored by Olivier St-Onge's avatar Olivier St-Onge
Browse files

Fix bug where some resizing events where ignored

Resizing an icon tile on the edge would recompose that tile down a row. The initial resizing state was dropped and the tile remained small in QS.
This was initially done to avoid saving an unecessary snapshot, which would cause the Undo button to appear.
As an alternative, collect all resizing operations and filter out which one would apply a change

Test: manually
Test: ResizingTest
Flag: com.android.systemui.qs_ui_refactor_compose_fragment
Fixes: 409564266
Change-Id: If02347e9e1e82950cf58086c61f1f92117fb2050
parent 80a9d9d9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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()
+8 −7
Original line number Diff line number Diff line
@@ -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
@@ -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))
                        }
                    }
                }
            }
        }
@@ -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)
        }
+65 −9
Original line number Diff line number Diff line
@@ -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,
@@ -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 -> {}
                }
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {