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

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

Merge "Implement stretch option for QS tiles" into main

parents daf6106e 34dffcd6
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -29,8 +29,10 @@ import com.android.systemui.qs.panels.domain.interactor.NoopGridConsistencyInter
import com.android.systemui.qs.panels.shared.model.GridConsistencyLog
import com.android.systemui.qs.panels.shared.model.GridLayoutType
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
import com.android.systemui.qs.panels.shared.model.StretchedGridLayoutType
import com.android.systemui.qs.panels.ui.compose.GridLayout
import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout
import com.android.systemui.qs.panels.ui.compose.StretchedGridLayout
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -62,6 +64,14 @@ interface PanelsModule {
            return Pair(InfiniteGridLayoutType, gridLayout)
        }

        @Provides
        @IntoSet
        fun provideStretchedGridLayout(
            gridLayout: StretchedGridLayout
        ): Pair<GridLayoutType, GridLayout> {
            return Pair(StretchedGridLayoutType, gridLayout)
        }

        @Provides
        fun provideGridLayoutMap(
            entries: Set<@JvmSuppressWildcards Pair<GridLayoutType, GridLayout>>
@@ -69,6 +79,13 @@ interface PanelsModule {
            return entries.toMap()
        }

        @Provides
        fun provideGridLayoutTypes(
            entries: Set<@JvmSuppressWildcards Pair<GridLayoutType, GridLayout>>
        ): Set<GridLayoutType> {
            return entries.map { it.first }.toSet()
        }

        @Provides
        @IntoSet
        fun provideGridConsistencyInteractor(
@@ -77,6 +94,14 @@ interface PanelsModule {
            return Pair(InfiniteGridLayoutType, consistencyInteractor)
        }

        @Provides
        @IntoSet
        fun provideStretchedGridConsistencyInteractor(
            consistencyInteractor: NoopGridConsistencyInteractor
        ): Pair<GridLayoutType, GridTypeConsistencyInteractor> {
            return Pair(StretchedGridLayoutType, consistencyInteractor)
        }

        @Provides
        fun provideGridConsistencyInteractorMap(
            entries: Set<@JvmSuppressWildcards Pair<GridLayoutType, GridTypeConsistencyInteractor>>
+7 −0
Original line number Diff line number Diff line
@@ -26,10 +26,17 @@ import kotlinx.coroutines.flow.asStateFlow

interface GridLayoutTypeRepository {
    val layout: StateFlow<GridLayoutType>
    fun setLayout(type: GridLayoutType)
}

@SysUISingleton
class GridLayoutTypeRepositoryImpl @Inject constructor() : GridLayoutTypeRepository {
    private val _layout: MutableStateFlow<GridLayoutType> = MutableStateFlow(InfiniteGridLayoutType)
    override val layout = _layout.asStateFlow()

    override fun setLayout(type: GridLayoutType) {
        if (_layout.value != type) {
            _layout.value = type
        }
    }
}
+7 −3
Original line number Diff line number Diff line
@@ -20,9 +20,13 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepository
import com.android.systemui.qs.panels.shared.model.GridLayoutType
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

@SysUISingleton
class GridLayoutTypeInteractor @Inject constructor(repo: GridLayoutTypeRepository) {
    val layout: Flow<GridLayoutType> = repo.layout
class GridLayoutTypeInteractor @Inject constructor(private val repo: GridLayoutTypeRepository) {
    val layout: StateFlow<GridLayoutType> = repo.layout

    fun setLayoutType(type: GridLayoutType) {
        repo.setLayout(type)
    }
}
+8 −43
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.qs.panels.domain.interactor

import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.TileRow
import com.android.systemui.qs.pipeline.shared.TileSpec
import javax.inject.Inject

@@ -35,7 +37,7 @@ constructor(
     */
    override fun reconcileTiles(tiles: List<TileSpec>): List<TileSpec> {
        val newTiles: MutableList<TileSpec> = mutableListOf()
        val row = TileRow(columns = gridSizeInteractor.columns.value)
        val row = TileRow<TileSpec>(columns = gridSizeInteractor.columns.value)
        val iconTilesSet = iconTilesInteractor.iconTilesSpecs.value
        val tilesQueue =
            ArrayDeque(
@@ -54,7 +56,7 @@ constructor(

        while (tilesQueue.isNotEmpty()) {
            if (row.isFull()) {
                newTiles.addAll(row.tileSpecs())
                newTiles.addAll(row.tiles.map { it.tile })
                row.clear()
            }

@@ -66,13 +68,13 @@ constructor(
                // We'll try to either add an icon tile from the queue to complete the row, or
                // remove an icon tile from the current row to free up space.

                val iconTile: SizedTile? = tilesQueue.firstOrNull { it.width == 1 }
                val iconTile: SizedTile<TileSpec>? = tilesQueue.firstOrNull { it.width == 1 }
                if (iconTile != null) {
                    tilesQueue.remove(iconTile)
                    tilesQueue.addFirst(tile)
                    row.maybeAddTile(iconTile)
                } else {
                    val tileToRemove: SizedTile? = row.findLastIconTile()
                    val tileToRemove: SizedTile<TileSpec>? = row.findLastIconTile()
                    if (tileToRemove != null) {
                        row.removeTile(tileToRemove)
                        row.maybeAddTile(tile)
@@ -84,7 +86,7 @@ constructor(
                        // If the row does not have an icon tile, add the incomplete row.
                        // Note: this shouldn't happen because an icon tile is guaranteed to be in a
                        // row that doesn't have enough space for a large tile.
                        val tileSpecs = row.tileSpecs()
                        val tileSpecs = row.tiles.map { it.tile }
                        Log.wtf(TAG, "Uneven row does not have an icon tile to remove: $tileSpecs")
                        newTiles.addAll(tileSpecs)
                        row.clear()
@@ -95,48 +97,11 @@ constructor(
        }

        // Add last row that might be incomplete
        newTiles.addAll(row.tileSpecs())
        newTiles.addAll(row.tiles.map { it.tile })

        return newTiles.toList()
    }

    /** Tile with a width representing the number of columns it should take. */
    private data class SizedTile(val spec: TileSpec, val width: Int)

    private class TileRow(private val columns: Int) {
        private var availableColumns = columns
        private val tiles: MutableList<SizedTile> = mutableListOf()

        fun tileSpecs(): List<TileSpec> {
            return tiles.map { it.spec }
        }

        fun maybeAddTile(tile: SizedTile): Boolean {
            if (availableColumns - tile.width >= 0) {
                tiles.add(tile)
                availableColumns -= tile.width
                return true
            }
            return false
        }

        fun findLastIconTile(): SizedTile? {
            return tiles.findLast { it.width == 1 }
        }

        fun removeTile(tile: SizedTile) {
            tiles.remove(tile)
            availableColumns += tile.width
        }

        fun clear() {
            tiles.clear()
            availableColumns = columns
        }

        fun isFull(): Boolean = availableColumns == 0
    }

    private companion object {
        const val TAG = "InfiniteGridConsistencyInteractor"
    }
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.qs.panels.domain.interactor

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.pipeline.shared.TileSpec
import javax.inject.Inject

@SysUISingleton
class NoopConsistencyInteractor @Inject constructor() : GridTypeConsistencyInteractor {
    override fun reconcileTiles(tiles: List<TileSpec>): List<TileSpec> = tiles
}
Loading