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

Commit 5db7bdf3 authored by Olivier St-Onge's avatar Olivier St-Onge Committed by Android (Google) Code Review
Browse files

Merge changes I53ec9c3b,I5931d3a0 into main

* changes:
  Small fixes for Edit mode
  Avoid recreating the SnapshotStateList for edit mode at every changes
parents c3aecd95 a5906cf3
Loading
Loading
Loading
Loading
+75 −44
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.compose.selection.PlacementEvent
import com.android.systemui.qs.panels.ui.model.GridCell
@@ -36,23 +35,26 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class EditTileListStateTest : SysuiTestCase() {
    private val underTest = EditTileListState(TestEditTiles, columns = 4, largeTilesSpan = 2)
    private val underTest =
        EditTileListState(TestEditTiles, TestLargeTiles, columns = 4, largeTilesSpan = 2)

    @Test
    fun startDrag_listHasSpacers() {
        underTest.onStarted(TestEditTiles[0], DragType.Add)
        val cell = underTest.tiles[0] as TileGridCell
        underTest.onStarted(cell, DragType.Add)

        // [ a ] [ b ] [ c ] [ X ]
        // [ Large D ] [ e ] [ X ]
        assertThat(underTest.tiles.toStrings())
            .isEqualTo(listOf("a", "b", "c", "spacer", "d", "e", "spacer"))
        assertThat(underTest.isMoving(TestEditTiles[0].tile.tileSpec)).isTrue()
        assertThat(underTest.isMoving(cell.tile.tileSpec)).isTrue()
        assertThat(underTest.dragInProgress).isTrue()
    }

    @Test
    fun moveDrag_listChanges() {
        underTest.onStarted(TestEditTiles[4], DragType.Add)
        val cell = underTest.tiles[5] as TileGridCell
        underTest.onStarted(cell, DragType.Add)
        underTest.onTargeting(3, false)

        // Tile E goes to index 3
@@ -64,7 +66,7 @@ class EditTileListStateTest : SysuiTestCase() {

    @Test
    fun moveDragOnSidesOfLargeTile_listChanges() {
        val draggedCell = TestEditTiles[4]
        val draggedCell = underTest.tiles[5] as TileGridCell

        underTest.onStarted(draggedCell, DragType.Add)
        underTest.onTargeting(4, true)
@@ -86,7 +88,7 @@ class EditTileListStateTest : SysuiTestCase() {

    @Test
    fun moveNewTile_tileIsAdded() {
        val newTile = createEditTile("newTile", 2)
        val newTile = SizedTileImpl(createEditTile("newTile"), 2)

        underTest.onStarted(newTile, DragType.Add)
        underTest.onTargeting(5, false)
@@ -103,18 +105,19 @@ class EditTileListStateTest : SysuiTestCase() {

    @Test
    fun movedTileOutOfBounds_tileDisappears() {
        underTest.onStarted(TestEditTiles[0], DragType.Add)
        val cell = underTest.tiles[0] as TileGridCell
        underTest.onStarted(cell, DragType.Add)
        underTest.movedOutOfBounds()

        assertThat(underTest.tiles.toStrings()).doesNotContain(TestEditTiles[0].tile.tileSpec.spec)
        assertThat(underTest.tiles.toStrings()).doesNotContain(TestEditTiles[0].tileSpec.spec)
    }

    @Test
    fun targetIndexForPlacementToTileSpec_returnsCorrectIndex() {
        val placementEvent =
            PlacementEvent.PlaceToTileSpec(
                movingSpec = TestEditTiles[0].tile.tileSpec,
                targetSpec = TestEditTiles[3].tile.tileSpec,
                movingSpec = TestEditTiles[0].tileSpec,
                targetSpec = TestEditTiles[3].tileSpec,
            )
        val index = underTest.targetIndexForPlacement(placementEvent)

@@ -124,19 +127,13 @@ class EditTileListStateTest : SysuiTestCase() {
    @Test
    fun targetIndexForPlacementToIndex_indexOutOfBounds_returnsCorrectIndex() {
        val placementEventTooLow =
            PlacementEvent.PlaceToIndex(
                movingSpec = TestEditTiles[0].tile.tileSpec,
                targetIndex = -1,
            )
            PlacementEvent.PlaceToIndex(movingSpec = TestEditTiles[0].tileSpec, targetIndex = -1)
        val index1 = underTest.targetIndexForPlacement(placementEventTooLow)

        assertThat(index1).isEqualTo(0)

        val placementEventTooHigh =
            PlacementEvent.PlaceToIndex(
                movingSpec = TestEditTiles[0].tile.tileSpec,
                targetIndex = 10,
            )
            PlacementEvent.PlaceToIndex(movingSpec = TestEditTiles[0].tileSpec, targetIndex = 10)
        val index2 = underTest.targetIndexForPlacement(placementEventTooHigh)
        assertThat(index2).isEqualTo(TestEditTiles.size)
    }
@@ -151,10 +148,7 @@ class EditTileListStateTest : SysuiTestCase() {
         * 'e' is now at index 3
         */
        val placementEvent =
            PlacementEvent.PlaceToIndex(
                movingSpec = TestEditTiles[4].tile.tileSpec,
                targetIndex = 3,
            )
            PlacementEvent.PlaceToIndex(movingSpec = TestEditTiles[4].tileSpec, targetIndex = 3)
        val index = underTest.targetIndexForPlacement(placementEvent)

        assertThat(index).isEqualTo(3)
@@ -170,15 +164,54 @@ class EditTileListStateTest : SysuiTestCase() {
         * 'a' is now at index 2
         */
        val placementEvent =
            PlacementEvent.PlaceToIndex(
                movingSpec = TestEditTiles[0].tile.tileSpec,
                targetIndex = 3,
            )
            PlacementEvent.PlaceToIndex(movingSpec = TestEditTiles[0].tileSpec, targetIndex = 3)
        val index = underTest.targetIndexForPlacement(placementEvent)

        assertThat(index).isEqualTo(2)
    }

    @Test
    fun updateTiles_shouldRearrangeGrid() {
        val newTiles =
            listOf(
                createEditTile("1"),
                createEditTile("2"),
                createEditTile("3"),
                createEditTile("4"),
                createEditTile("5"),
                createEditTile("6"),
                createEditTile("7"),
                createEditTile("8"),
            )
        underTest.updateTiles(
            newTiles,
            largeTiles =
                setOf(
                    newTiles[0].tileSpec,
                    newTiles[1].tileSpec,
                    newTiles[6].tileSpec,
                    newTiles[7].tileSpec,
                ),
        )

        // Update should result in
        // [ Large 1 ] [ Large 2 ]
        // [ 3 ] [ 4 ] [ 5 ] [ 6 ]
        // [ Large 7 ] [ Large 8 ]

        assertThat(underTest.tiles)
            .containsExactly(
                TileGridCell(newTiles[0], row = 0, column = 0, width = 2),
                TileGridCell(newTiles[1], row = 0, column = 2, width = 2),
                TileGridCell(newTiles[2], row = 1, column = 0, width = 1),
                TileGridCell(newTiles[3], row = 1, column = 1, width = 1),
                TileGridCell(newTiles[4], row = 1, column = 2, width = 1),
                TileGridCell(newTiles[5], row = 1, column = 3, width = 1),
                TileGridCell(newTiles[6], row = 2, column = 0, width = 2),
                TileGridCell(newTiles[7], row = 2, column = 2, width = 2),
            )
    }

    private fun List<GridCell>.toStrings(): List<String> {
        return map {
            if (it is TileGridCell) {
@@ -190,9 +223,8 @@ class EditTileListStateTest : SysuiTestCase() {
    }

    companion object {
        private fun createEditTile(tileSpec: String, width: Int): SizedTile<EditTileViewModel> {
            return SizedTileImpl(
                EditTileViewModel(
        private fun createEditTile(tileSpec: String): EditTileViewModel {
            return EditTileViewModel(
                tileSpec = TileSpec.create(tileSpec),
                icon = Icon.Resource(0, null),
                label = AnnotatedString("unused"),
@@ -200,8 +232,6 @@ class EditTileListStateTest : SysuiTestCase() {
                isCurrent = true,
                availableEditActions = emptySet(),
                category = TileCategory.UNKNOWN,
                ),
                width,
            )
        }

@@ -209,11 +239,12 @@ class EditTileListStateTest : SysuiTestCase() {
        // [ Large D ] [ e ] [ f ]
        private val TestEditTiles =
            listOf(
                createEditTile("a", 1),
                createEditTile("b", 1),
                createEditTile("c", 1),
                createEditTile("d", 2),
                createEditTile("e", 1),
                createEditTile("a"),
                createEditTile("b"),
                createEditTile("c"),
                createEditTile("d"),
                createEditTile("e"),
            )
        private val TestLargeTiles = setOf(TileSpec.create("d"))
    }
}
+40 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.qs.panels.ui.compose.selection

import androidx.compose.foundation.gestures.DraggableAnchors
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -30,7 +31,14 @@ import org.junit.runner.RunWith
class ResizingStateTest : SysuiTestCase() {

    private val underTest =
        ResizingState(TileSpec.create("a"), startsAsIcon = true).apply { updateAnchors(10f, 20f) }
        ResizingState(TileSpec.create("a"), startsAsIcon = true).apply {
            anchoredDraggableState.updateAnchors(
                DraggableAnchors {
                    QSDragAnchor.Icon at 10f
                    QSDragAnchor.Large at 20f
                }
            )
        }

    @Test
    fun newResizingState_setInitialValueCorrectly() {
@@ -38,8 +46,37 @@ class ResizingStateTest : SysuiTestCase() {
    }

    @Test
    fun updateAnchors_setBoundsCorrectly() {
        assertThat(underTest.bounds).isEqualTo(10f to 20f)
    fun updateAnchors_onIconTile_setBoundsCorrectly() {
        // With an icon tile 10px wide, and a max span of 2 with a tile padding of 5
        underTest.updateAnchors(isIcon = true, 10, maxSpan = 2, padding = 5)

        // New bounds should be: 10 to 25
        // max = 10 * 2 + 5 * (2 - 1)
        assertThat(underTest.bounds).isEqualTo(10f to 25f)

        // With an icon tile 5px wide, and a max span of 10 with a tile padding of 15
        underTest.updateAnchors(isIcon = true, 5, maxSpan = 10, padding = 15)

        // New bounds should be: 5 to 185
        // max = 5 * 10 + 15 * (10 - 1)
        assertThat(underTest.bounds).isEqualTo(5f to 185f)
    }

    @Test
    fun updateAnchors_onLargeTile_setBoundsCorrectly() {
        // With a large tile 60px wide, and a max span of 2 with a tile padding of 20
        underTest.updateAnchors(isIcon = false, 60, maxSpan = 2, padding = 20)

        // New bounds should be: 20 to 60
        // min = (60 - (20 * (2 - 1))) / 2
        assertThat(underTest.bounds).isEqualTo(20f to 60f)

        // With a large tile 35px wide, and a max span of 5 with a tile padding of 2
        underTest.updateAnchors(isIcon = false, 36, maxSpan = 6, padding = 2)

        // New bounds should be: 4 to 36
        // min = (46 - (2 * (6 - 1))) / 6
        assertThat(underTest.bounds).isEqualTo(4f to 36f)
    }

    @Test
+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ private fun DragAndDropEvent.toOffset(): Offset {
private fun insertAfter(item: LazyGridItemInfo, offset: Offset): Boolean {
    // We want to insert the tile after the target if we're aiming at the end of a large tile
    // TODO(ostonge): Verify this behavior in RTL
    val itemCenter = item.offset.x + item.size.width * .75
    val itemCenter = item.offset.x + item.size.width * .5
    return item.span != 1 && offset.x > itemCenter
}

+38 −29
Original line number Diff line number Diff line
@@ -16,15 +16,14 @@

package com.android.systemui.qs.panels.ui.compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.geometry.Offset
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.compose.selection.PlacementEvent
import com.android.systemui.qs.panels.ui.model.GridCell
import com.android.systemui.qs.panels.ui.model.TileGridCell
@@ -33,24 +32,14 @@ import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec

/**
 * Creates the edit tile list state that is remembered across compositions.
 *
 * Changes to the tiles or columns will recreate the state.
 * Holds the state for the tiles to display and builds a grid using their sizes and the available
 * columns.
 */
@Composable
fun rememberEditListState(
    tiles: List<SizedTile<EditTileViewModel>>,
    columns: Int,
    largeTilesSpan: Int,
): EditTileListState {
    return remember(tiles, columns) { EditTileListState(tiles, columns, largeTilesSpan) }
}

/** Holds the temporary state of the tile list during a drag movement where we move tiles around. */
class EditTileListState(
    tiles: List<SizedTile<EditTileViewModel>>,
    private val columns: Int,
    private val largeTilesSpan: Int,
    initialTiles: List<EditTileViewModel>,
    initialLargeTiles: Set<TileSpec>,
    val columns: Int,
    val largeTilesSpan: Int,
) : DragAndDropState {
    override var draggedCell by mutableStateOf<SizedTile<EditTileViewModel>?>(null)
        private set
@@ -70,9 +59,18 @@ class EditTileListState(
        get() = draggedCell != null

    private val _tiles: SnapshotStateList<GridCell> =
        tiles.toGridCells(columns).toMutableStateList()
    val tiles: List<GridCell>
        get() = _tiles.toList()
        initialTiles.toGridCells(initialLargeTiles).toMutableStateList()
    val tiles: List<GridCell> = _tiles

    /** Update the grid with this new list of tiles and new set of large tileSpecs. */
    fun updateTiles(tiles: List<EditTileViewModel>, largeTiles: Set<TileSpec>) {
        tiles.toGridCells(largeTiles).let {
            _tiles.apply {
                clear()
                addAll(it)
            }
        }
    }

    fun tileSpecs(): List<TileSpec> {
        return _tiles.filterIsInstance<TileGridCell>().map { it.tile.tileSpec }
@@ -82,12 +80,6 @@ class EditTileListState(
        return _tiles.indexOfFirst { it is TileGridCell && it.tile.tileSpec == tileSpec }
    }

    fun isRemovable(tileSpec: TileSpec): Boolean {
        return _tiles.find {
            it is TileGridCell && it.tile.tileSpec == tileSpec && it.tile.isRemovable
        } != null
    }

    /** Resize the tile corresponding to the [TileSpec] to [toIcon] */
    fun resizeTile(tileSpec: TileSpec, toIcon: Boolean) {
        val fromIndex = indexOf(tileSpec)
@@ -96,8 +88,7 @@ class EditTileListState(

            if (cell.isIcon == toIcon) return

            _tiles.removeAt(fromIndex)
            _tiles.add(fromIndex, cell.copy(width = if (toIcon) 1 else largeTilesSpan))
            _tiles[fromIndex] = cell.copy(width = if (toIcon) 1 else largeTilesSpan)
            regenerateGrid(fromIndex)
        }
    }
@@ -195,6 +186,24 @@ class EditTileListState(
        }
    }

    private fun List<TileGridCell>.updateLargeWidth(
        previousWidth: Int,
        newWidth: Int,
    ): List<TileGridCell> {
        return if (previousWidth != newWidth) {
            map { if (!it.isIcon) it.copy(width = newWidth) else it }
        } else {
            this
        }
    }

    private fun List<EditTileViewModel>.toGridCells(largeTiles: Set<TileSpec>): List<GridCell> {
        return map {
                SizedTileImpl(it, if (largeTiles.contains(it.tileSpec)) largeTilesSpan else 1)
            }
            .toGridCells(columns)
    }

    /** Regenerate the list of [GridCell] with their new potential rows */
    private fun regenerateGrid() {
        _tiles.filterIsInstance<TileGridCell>().toGridCells(columns).let {
+72 −97

File changed.

Preview size limit exceeded, changes collapsed.

Loading