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

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

Merge "Add statusbar command to set large QS tiles" into main

parents 965ab67d 58147b35
Loading
Loading
Loading
Loading
+107 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.startable

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
import com.android.systemui.qs.panels.domain.interactor.iconTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.statusbar.commandline.commandRegistry
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.io.StringWriter
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class QSLargeSpecsCommandTest : SysuiTestCase() {
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val Kosmos.underTest by Kosmos.Fixture { qsLargeSpecsCommand }

    @Before fun setUp() = kosmos.run { underTest.start() }

    @Test
    fun commandSetLargeSpecs_correctlySetsSpecs() =
        kosmos.runTest {
            val largeSpecs by collectLastValue(iconTilesInteractor.largeTilesSpecs)

            // Assert default state
            assertThat(largeSpecs)
                .containsAtLeastElementsIn(defaultLargeTilesRepository.defaultLargeTiles)

            // Sets new large tiles
            commandRegistry.onShellCommand(
                PrintWriter(StringWriter()),
                arrayOf("set-large-tiles", "airplane,rotation,flashlight"),
            )

            // Assert new state
            assertThat(largeSpecs)
                .containsExactly(
                    TileSpec.create("airplane"),
                    TileSpec.create("rotation"),
                    TileSpec.create("flashlight"),
                )
        }

    @Test
    fun commandSetLargeSpecs_correctlyRemovesAllSpecs() =
        kosmos.runTest {
            val largeSpecs by collectLastValue(iconTilesInteractor.largeTilesSpecs)

            // Assert default state
            assertThat(largeSpecs)
                .containsAtLeastElementsIn(defaultLargeTilesRepository.defaultLargeTiles)

            // Sets an empty set of specs
            commandRegistry.onShellCommand(PrintWriter(StringWriter()), arrayOf("set-large-tiles"))

            // Assert empty set
            assertThat(largeSpecs).isEmpty()
        }

    @Test
    fun commandRestoreLargeSpecs_correctlyRestoresDefault() =
        kosmos.runTest {
            val largeSpecs by collectLastValue(iconTilesInteractor.largeTilesSpecs)

            // Sets new large tile
            iconTilesInteractor.setLargeTiles(setOf(TileSpec.create("bt")))

            // Assert new state
            assertThat(largeSpecs).containsExactly(TileSpec.create("bt"))

            // Sets new large tiles
            commandRegistry.onShellCommand(
                PrintWriter(StringWriter()),
                arrayOf("restore-large-tiles"),
            )

            // Assert default state
            assertThat(largeSpecs)
                .containsAtLeastElementsIn(defaultLargeTilesRepository.defaultLargeTiles)
        }
}
+6 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.qs.panels.data.repository.AppIconRepository
import com.android.systemui.qs.panels.data.repository.AppIconRepositoryImpl
import com.android.systemui.qs.panels.domain.interactor.EditTilesResetInteractor
import com.android.systemui.qs.panels.domain.interactor.SizedTilesResetInteractor
import com.android.systemui.qs.panels.domain.startable.QSLargeSpecsCommand
import com.android.systemui.qs.panels.domain.startable.QSPanelsCoreStartable
import com.android.systemui.qs.panels.shared.model.GridLayoutType
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
@@ -65,6 +66,11 @@ interface PanelsModuleBase {
    @ClassKey(QSPanelsCoreStartable::class)
    fun bindQSPanelsCoreStartable(impl: QSPanelsCoreStartable): CoreStartable

    @Binds
    @IntoMap
    @ClassKey(QSLargeSpecsCommand::class)
    fun bindQSLargeSpecsCommand(impl: QSLargeSpecsCommand): CoreStartable

    @Binds
    fun bindsAppIconRepositoryFactory(
        impl: AppIconRepositoryImpl.Factory
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.startable

import com.android.systemui.CoreStartable
import com.android.systemui.qs.panels.domain.interactor.IconTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
import javax.inject.Inject

class QSLargeSpecsCommand
@Inject
constructor(
    private val commandRegistry: CommandRegistry,
    private val iconTilesInteractor: IconTilesInteractor,
) : CoreStartable {
    override fun start() {
        commandRegistry.registerCommand(SetLargeTilesCommand.COMMAND) {
            SetLargeTilesCommand(iconTilesInteractor)
        }
        commandRegistry.registerCommand(RestoreLargeTilesCommand.COMMAND) {
            RestoreLargeTilesCommand(iconTilesInteractor)
        }
    }
}

class SetLargeTilesCommand(private val iconTilesInteractor: IconTilesInteractor) : Command {
    override fun execute(pw: PrintWriter, args: List<String>) {
        val specs =
            if (args.isEmpty()) {
                emptySet()
            } else {
                args[0].split(",").map(TileSpec::create).toSet()
            }

        pw.println("Setting large specs: $specs")
        iconTilesInteractor.setLargeTiles(specs)
    }

    override fun help(pw: PrintWriter) {
        pw.println("Usage: $COMMAND [comma separated list of tiles]")
        pw.println("    Sets the list of large tiles to use in Quick Settings tiles")
    }

    companion object {
        const val COMMAND: String = "set-large-tiles"
    }
}

class RestoreLargeTilesCommand(private val iconTilesInteractor: IconTilesInteractor) : Command {
    override fun execute(pw: PrintWriter, args: List<String>) {
        pw.println("Setting large specs to default")
        iconTilesInteractor.resetToDefault()
    }

    override fun help(pw: PrintWriter) {
        pw.println("Usage: $COMMAND")
        pw.println("    Restore the default list of large tiles to use in Quick Settings tiles")
    }

    companion object {
        const val COMMAND: String = "restore-large-tiles"
    }
}
+24 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.startable

import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.domain.interactor.iconTilesInteractor
import com.android.systemui.statusbar.commandline.commandRegistry

val Kosmos.qsLargeSpecsCommand by
    Kosmos.Fixture { QSLargeSpecsCommand(commandRegistry, iconTilesInteractor) }