Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt→packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt +22 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.kosmos.testScope import com.android.systemui.shade.ShadePrimaryDisplayCommand import com.android.systemui.statusbar.commandline.commandRegistry import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat Loading @@ -34,13 +36,16 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ShadeDisplaysRepositoryTest : SysuiTestCase() { class ShadePrimaryDisplayCommandTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val commandRegistry = kosmos.commandRegistry private val displayRepository = kosmos.displayRepository private val shadeDisplaysRepository = ShadeDisplaysRepositoryImpl() private val pw = PrintWriter(StringWriter()) private val underTest = ShadeDisplaysRepositoryImpl(commandRegistry) private val underTest = ShadePrimaryDisplayCommand(commandRegistry, displayRepository, shadeDisplaysRepository) @Before fun setUp() { Loading @@ -50,7 +55,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() { @Test fun commandDisplayOverride_updatesDisplayId() = testScope.runTest { val displayId by collectLastValue(underTest.displayId) val displayId by collectLastValue(shadeDisplaysRepository.displayId) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) val newDisplayId = 2 Loading @@ -65,7 +70,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() { @Test fun commandShadeDisplayOverride_resetsDisplayId() = testScope.runTest { val displayId by collectLastValue(underTest.displayId) val displayId by collectLastValue(shadeDisplaysRepository.displayId) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) val newDisplayId = 2 Loading @@ -78,4 +83,17 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() { commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", "reset")) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) } @Test fun commandShadeDisplayOverride_anyExternalDisplay_notOnDefaultAnymore() = testScope.runTest { val displayId by collectLastValue(shadeDisplaysRepository.displayId) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) val newDisplayId = 2 displayRepository.addDisplay(displayId = newDisplayId) commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", "any_external")) assertThat(displayId).isEqualTo(newDisplayId) } } packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt +2 −4 Original line number Diff line number Diff line Loading @@ -164,10 +164,8 @@ object ShadeDisplayAwareModule { @Provides @IntoMap @ClassKey(ShadeDisplaysRepositoryImpl::class) fun provideShadePositionRepositoryAsCoreStartable( impl: ShadeDisplaysRepositoryImpl ): CoreStartable { @ClassKey(ShadePrimaryDisplayCommand::class) fun provideShadePrimaryDisplayCommand(impl: ShadePrimaryDisplayCommand): CoreStartable { return if (ShadeWindowGoesAround.isEnabled) { impl } else { Loading packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt +87 −20 Original line number Diff line number Diff line Loading @@ -17,40 +17,107 @@ package com.android.systemui.shade import android.view.Display import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.display.data.repository.DisplayRepository import com.android.systemui.shade.data.repository.ShadeDisplaysRepository import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import java.io.PrintWriter import javax.inject.Inject class ShadePrimaryDisplayCommand(private val positionRepository: ShadeDisplaysRepository) : Command { @SysUISingleton class ShadePrimaryDisplayCommand @Inject constructor( private val commandRegistry: CommandRegistry, private val displaysRepository: DisplayRepository, private val positionRepository: ShadeDisplaysRepository, ) : Command, CoreStartable { override fun start() { commandRegistry.registerCommand("shade_display_override") { this } } override fun help(pw: PrintWriter) { pw.println("shade_display_override <displayId> ") pw.println("Set the display which is holding the shade.") pw.println() pw.println("shade_display_override reset ") pw.println("Reset the display which is holding the shade.") pw.println() pw.println("shade_display_override (list|status) ") pw.println("Lists available displays and which has the shade") pw.println() pw.println("shade_display_override any_external") pw.println("Moves the shade to the first not-default display available") } override fun execute(pw: PrintWriter, args: List<String>) { if (args[0].lowercase() == "reset") { CommandHandler(pw, args).execute() } /** Wrapper class to avoid propagating [PrintWriter] to all methods. */ private inner class CommandHandler( private val pw: PrintWriter, private val args: List<String>, ) { fun execute() { when (val command = args.getOrNull(0)?.lowercase()) { "reset" -> reset() "list", "status" -> printStatus() "any_external" -> anyExternal() else -> { val cmdAsInteger = command?.toIntOrNull() if (cmdAsInteger != null) { changeDisplay(displayId = cmdAsInteger) } else { help(pw) } } } } private fun reset() { positionRepository.resetDisplayId() pw.println("Reset shade primary display id to ${Display.DEFAULT_DISPLAY}") return } val displayId: Int = try { args[0].toInt() } catch (e: NumberFormatException) { pw.println("Error: task id should be an integer") private fun printStatus() { val displays = displaysRepository.displays.value val shadeDisplay = positionRepository.displayId.value pw.println("Available displays: ") displays.forEach { pw.print(" - ${it.displayId}") pw.println(if (it.displayId == shadeDisplay) " (Shade window is here)" else "") } } private fun anyExternal() { val anyExternalDisplay = displaysRepository.displays.value.firstOrNull { it.displayId != Display.DEFAULT_DISPLAY } if (anyExternalDisplay == null) { pw.println("No external displays available.") return } setDisplay(anyExternalDisplay.displayId) } private fun changeDisplay(displayId: Int) { if (displayId < 0) { pw.println("Error: display id should be positive integer") } positionRepository.setDisplayId(displayId) pw.println("New shade primary display id is $displayId") setDisplay(displayId) } override fun help(pw: PrintWriter) { pw.println("shade_display_override <displayId> ") pw.println("Set the display which is holding the shade.") pw.println("shade_display_override reset ") pw.println("Reset the display which is holding the shade.") private fun setDisplay(id: Int) { positionRepository.setDisplayId(id) pw.println("New shade primary display id is $id") } } } packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt +1 −12 Original line number Diff line number Diff line Loading @@ -17,10 +17,7 @@ package com.android.systemui.shade.data.repository import android.view.Display import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.shade.ShadePrimaryDisplayCommand import com.android.systemui.statusbar.commandline.CommandRegistry import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow Loading @@ -41,9 +38,7 @@ interface ShadeDisplaysRepository { /** Source of truth for the display currently holding the shade. */ @SysUISingleton class ShadeDisplaysRepositoryImpl @Inject constructor(private val commandRegistry: CommandRegistry) : ShadeDisplaysRepository, CoreStartable { class ShadeDisplaysRepositoryImpl @Inject constructor() : ShadeDisplaysRepository { private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY) override val displayId: StateFlow<Int> Loading @@ -56,10 +51,4 @@ constructor(private val commandRegistry: CommandRegistry) : ShadeDisplaysReposit override fun resetDisplayId() { _displayId.value = Display.DEFAULT_DISPLAY } override fun start() { commandRegistry.registerCommand("shade_display_override") { ShadePrimaryDisplayCommand(this) } } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt→packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt +22 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.kosmos.testScope import com.android.systemui.shade.ShadePrimaryDisplayCommand import com.android.systemui.statusbar.commandline.commandRegistry import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat Loading @@ -34,13 +36,16 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ShadeDisplaysRepositoryTest : SysuiTestCase() { class ShadePrimaryDisplayCommandTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val commandRegistry = kosmos.commandRegistry private val displayRepository = kosmos.displayRepository private val shadeDisplaysRepository = ShadeDisplaysRepositoryImpl() private val pw = PrintWriter(StringWriter()) private val underTest = ShadeDisplaysRepositoryImpl(commandRegistry) private val underTest = ShadePrimaryDisplayCommand(commandRegistry, displayRepository, shadeDisplaysRepository) @Before fun setUp() { Loading @@ -50,7 +55,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() { @Test fun commandDisplayOverride_updatesDisplayId() = testScope.runTest { val displayId by collectLastValue(underTest.displayId) val displayId by collectLastValue(shadeDisplaysRepository.displayId) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) val newDisplayId = 2 Loading @@ -65,7 +70,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() { @Test fun commandShadeDisplayOverride_resetsDisplayId() = testScope.runTest { val displayId by collectLastValue(underTest.displayId) val displayId by collectLastValue(shadeDisplaysRepository.displayId) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) val newDisplayId = 2 Loading @@ -78,4 +83,17 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() { commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", "reset")) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) } @Test fun commandShadeDisplayOverride_anyExternalDisplay_notOnDefaultAnymore() = testScope.runTest { val displayId by collectLastValue(shadeDisplaysRepository.displayId) assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY) val newDisplayId = 2 displayRepository.addDisplay(displayId = newDisplayId) commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", "any_external")) assertThat(displayId).isEqualTo(newDisplayId) } }
packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt +2 −4 Original line number Diff line number Diff line Loading @@ -164,10 +164,8 @@ object ShadeDisplayAwareModule { @Provides @IntoMap @ClassKey(ShadeDisplaysRepositoryImpl::class) fun provideShadePositionRepositoryAsCoreStartable( impl: ShadeDisplaysRepositoryImpl ): CoreStartable { @ClassKey(ShadePrimaryDisplayCommand::class) fun provideShadePrimaryDisplayCommand(impl: ShadePrimaryDisplayCommand): CoreStartable { return if (ShadeWindowGoesAround.isEnabled) { impl } else { Loading
packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt +87 −20 Original line number Diff line number Diff line Loading @@ -17,40 +17,107 @@ package com.android.systemui.shade import android.view.Display import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.display.data.repository.DisplayRepository import com.android.systemui.shade.data.repository.ShadeDisplaysRepository import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import java.io.PrintWriter import javax.inject.Inject class ShadePrimaryDisplayCommand(private val positionRepository: ShadeDisplaysRepository) : Command { @SysUISingleton class ShadePrimaryDisplayCommand @Inject constructor( private val commandRegistry: CommandRegistry, private val displaysRepository: DisplayRepository, private val positionRepository: ShadeDisplaysRepository, ) : Command, CoreStartable { override fun start() { commandRegistry.registerCommand("shade_display_override") { this } } override fun help(pw: PrintWriter) { pw.println("shade_display_override <displayId> ") pw.println("Set the display which is holding the shade.") pw.println() pw.println("shade_display_override reset ") pw.println("Reset the display which is holding the shade.") pw.println() pw.println("shade_display_override (list|status) ") pw.println("Lists available displays and which has the shade") pw.println() pw.println("shade_display_override any_external") pw.println("Moves the shade to the first not-default display available") } override fun execute(pw: PrintWriter, args: List<String>) { if (args[0].lowercase() == "reset") { CommandHandler(pw, args).execute() } /** Wrapper class to avoid propagating [PrintWriter] to all methods. */ private inner class CommandHandler( private val pw: PrintWriter, private val args: List<String>, ) { fun execute() { when (val command = args.getOrNull(0)?.lowercase()) { "reset" -> reset() "list", "status" -> printStatus() "any_external" -> anyExternal() else -> { val cmdAsInteger = command?.toIntOrNull() if (cmdAsInteger != null) { changeDisplay(displayId = cmdAsInteger) } else { help(pw) } } } } private fun reset() { positionRepository.resetDisplayId() pw.println("Reset shade primary display id to ${Display.DEFAULT_DISPLAY}") return } val displayId: Int = try { args[0].toInt() } catch (e: NumberFormatException) { pw.println("Error: task id should be an integer") private fun printStatus() { val displays = displaysRepository.displays.value val shadeDisplay = positionRepository.displayId.value pw.println("Available displays: ") displays.forEach { pw.print(" - ${it.displayId}") pw.println(if (it.displayId == shadeDisplay) " (Shade window is here)" else "") } } private fun anyExternal() { val anyExternalDisplay = displaysRepository.displays.value.firstOrNull { it.displayId != Display.DEFAULT_DISPLAY } if (anyExternalDisplay == null) { pw.println("No external displays available.") return } setDisplay(anyExternalDisplay.displayId) } private fun changeDisplay(displayId: Int) { if (displayId < 0) { pw.println("Error: display id should be positive integer") } positionRepository.setDisplayId(displayId) pw.println("New shade primary display id is $displayId") setDisplay(displayId) } override fun help(pw: PrintWriter) { pw.println("shade_display_override <displayId> ") pw.println("Set the display which is holding the shade.") pw.println("shade_display_override reset ") pw.println("Reset the display which is holding the shade.") private fun setDisplay(id: Int) { positionRepository.setDisplayId(id) pw.println("New shade primary display id is $id") } } }
packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt +1 −12 Original line number Diff line number Diff line Loading @@ -17,10 +17,7 @@ package com.android.systemui.shade.data.repository import android.view.Display import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.shade.ShadePrimaryDisplayCommand import com.android.systemui.statusbar.commandline.CommandRegistry import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow Loading @@ -41,9 +38,7 @@ interface ShadeDisplaysRepository { /** Source of truth for the display currently holding the shade. */ @SysUISingleton class ShadeDisplaysRepositoryImpl @Inject constructor(private val commandRegistry: CommandRegistry) : ShadeDisplaysRepository, CoreStartable { class ShadeDisplaysRepositoryImpl @Inject constructor() : ShadeDisplaysRepository { private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY) override val displayId: StateFlow<Int> Loading @@ -56,10 +51,4 @@ constructor(private val commandRegistry: CommandRegistry) : ShadeDisplaysReposit override fun resetDisplayId() { _displayId.value = Display.DEFAULT_DISPLAY } override fun start() { commandRegistry.registerCommand("shade_display_override") { ShadePrimaryDisplayCommand(this) } } }