diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt index 31fadb13db08e..2f49c3fe863e1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt @@ -24,6 +24,7 @@ import com.android.systemui.controls.ControlStatus import com.android.systemui.util.UserAwareController import com.android.systemui.controls.management.ControlsFavoritingActivity import com.android.systemui.controls.ui.ControlsUiController +import com.android.systemui.controls.ui.SelectedItem import java.util.function.Consumer /** @@ -184,8 +185,8 @@ interface ControlsController : UserAwareController { */ fun countFavoritesForComponent(componentName: ComponentName): Int - /** See [ControlsUiController.getPreferredStructure]. */ - fun getPreferredStructure(): StructureInfo + /** See [ControlsUiController.getPreferredSelectedItem]. */ + fun getPreferredSelection(): SelectedItem /** * Interface for structure to pass data to [ControlsFavoritingActivity]. diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt index 50ce9d4ec0f4d..bdfe1fbeb4b55 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt @@ -38,6 +38,7 @@ import com.android.systemui.controls.ControlStatus import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.ui.ControlsUiController +import com.android.systemui.controls.ui.SelectedItem import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dump.DumpManager @@ -556,8 +557,8 @@ class ControlsControllerImpl @Inject constructor ( ) } - override fun getPreferredStructure(): StructureInfo { - return uiController.getPreferredStructure(getFavorites()) + override fun getPreferredSelection(): SelectedItem { + return uiController.getPreferredSelectedItem(getFavorites()) } override fun dump(pw: PrintWriter, args: Array) { diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt index 34bfa135f0c85..c8090bfb60e89 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt @@ -31,4 +31,9 @@ data class StructureInfo( val componentName: ComponentName, val structure: CharSequence, val controls: List -) +) { + companion object { + val EMPTY_COMPONENT = ComponentName("", "") + val EMPTY_STRUCTURE = StructureInfo(EMPTY_COMPONENT, "", mutableListOf()) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt index c1cfbcb0c2115..180e09e5aaf02 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt @@ -53,9 +53,43 @@ interface ControlsUiController { ) /** - * Returns the structure that is currently preferred by the user. + * Returns the element that is currently preferred by the user. * - * This structure will be the one that appears when the user first opens the controls activity. + * This element will be the one that appears when the user first opens the controls activity. */ - fun getPreferredStructure(structures: List): StructureInfo + fun getPreferredSelectedItem(structures: List): SelectedItem } + +sealed class SelectedItem { + + abstract val name: CharSequence + abstract val hasControls: Boolean + abstract val componentName: ComponentName + + /** + * Represents the currently selected item for a structure. + */ + data class StructureItem(val structure: StructureInfo) : SelectedItem() { + override val name: CharSequence = structure.structure + override val hasControls: Boolean = structure.controls.isNotEmpty() + override val componentName: ComponentName = structure.componentName + } + + /** + * Represents the currently selected item for a service that provides a panel activity. + * + * The [componentName] is that of the service, as that is the expected identifier that should + * not change (to always provide proper migration). + */ + data class PanelItem( + val appName: CharSequence, + override val componentName: + ComponentName + ) : SelectedItem() { + override val name: CharSequence = appName + override val hasControls: Boolean = true + } + companion object { + val EMPTY_SELECTION: SelectedItem = StructureItem(StructureInfo.EMPTY_STRUCTURE) + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 6cb0e8b048693..905636f563d13 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -41,13 +41,14 @@ import android.widget.LinearLayout import android.widget.ListPopupWindow import android.widget.Space import android.widget.TextView +import androidx.annotation.VisibleForTesting import com.android.systemui.R import com.android.systemui.controls.ControlsMetricsLogger import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.CustomIconCache -import com.android.systemui.controls.controller.ControlInfo import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.controller.StructureInfo +import com.android.systemui.controls.controller.StructureInfo.Companion.EMPTY_COMPONENT import com.android.systemui.controls.management.ControlAdapter import com.android.systemui.controls.management.ControlsEditingActivity import com.android.systemui.controls.management.ControlsFavoritingActivity @@ -90,24 +91,17 @@ class ControlsUiControllerImpl @Inject constructor ( companion object { private const val PREF_COMPONENT = "controls_component" - private const val PREF_STRUCTURE = "controls_structure" + private const val PREF_STRUCTURE_OR_APP_NAME = "controls_structure" + private const val PREF_IS_PANEL = "controls_is_panel" private const val FADE_IN_MILLIS = 200L - - private val EMPTY_COMPONENT = ComponentName("", "") - private val EMPTY_STRUCTURE = StructureInfo( - EMPTY_COMPONENT, - "", - mutableListOf() - ) } - private var selectedStructure: StructureInfo = EMPTY_STRUCTURE + private var selectedItem: SelectedItem = SelectedItem.EMPTY_SELECTION private lateinit var allStructures: List private val controlsById = mutableMapOf() private val controlViewsById = mutableMapOf() private lateinit var parent: ViewGroup - private lateinit var lastItems: List private var popup: ListPopupWindow? = null private var hidden = true private lateinit var onDismiss: Runnable @@ -128,10 +122,12 @@ class ControlsUiControllerImpl @Inject constructor ( private val onSeedingComplete = Consumer { accepted -> if (accepted) { - selectedStructure = controlsController.get().getFavorites().maxByOrNull { + selectedItem = controlsController.get().getFavorites().maxByOrNull { it.controls.size - } ?: EMPTY_STRUCTURE - updatePreferences(selectedStructure) + }?.let { + SelectedItem.StructureItem(it) + } ?: SelectedItem.EMPTY_SELECTION + updatePreferences(selectedItem) } reload(parent) } @@ -146,7 +142,15 @@ class ControlsUiControllerImpl @Inject constructor ( override fun onServicesUpdated(serviceInfos: List) { val lastItems = serviceInfos.map { val uid = it.serviceInfo.applicationInfo.uid - SelectionItem(it.loadLabel(), "", it.loadIcon(), it.componentName, uid) + + SelectionItem( + it.loadLabel(), + "", + it.loadIcon(), + it.componentName, + uid, + it.panelActivity + ) } uiExecutor.execute { parent.removeAllViews() @@ -160,11 +164,11 @@ class ControlsUiControllerImpl @Inject constructor ( override fun resolveActivity(): Class<*> { val allStructures = controlsController.get().getFavorites() - val selectedStructure = getPreferredStructure(allStructures) + val selected = getPreferredSelectedItem(allStructures) return if (controlsController.get().addSeedingFavoritesCallback(onSeedingComplete)) { ControlsActivity::class.java - } else if (selectedStructure.controls.isEmpty() && allStructures.size <= 1) { + } else if (!selected.hasControls && allStructures.size <= 1) { ControlsProviderSelectorActivity::class.java } else { ControlsActivity::class.java @@ -186,21 +190,24 @@ class ControlsUiControllerImpl @Inject constructor ( controlActionCoordinator.activityContext = activityContext allStructures = controlsController.get().getFavorites() - selectedStructure = getPreferredStructure(allStructures) + selectedItem = getPreferredSelectedItem(allStructures) if (controlsController.get().addSeedingFavoritesCallback(onSeedingComplete)) { listingCallback = createCallback(::showSeedingView) - } else if (selectedStructure.controls.isEmpty() && allStructures.size <= 1) { + } else if (!selectedItem.hasControls && allStructures.size <= 1) { // only show initial view if there are really no favorites across any structure listingCallback = createCallback(::showInitialSetupView) } else { - selectedStructure.controls.map { - ControlWithState(selectedStructure.componentName, it, null) - }.associateByTo(controlsById) { - ControlKey(selectedStructure.componentName, it.ci.controlId) + val selected = selectedItem + if (selected is SelectedItem.StructureItem) { + selected.structure.controls.map { + ControlWithState(selected.structure.componentName, it, null) + }.associateByTo(controlsById) { + ControlKey(selected.structure.componentName, it.ci.controlId) + } + controlsController.get().subscribeToFavorites(selected.structure) } listingCallback = createCallback(::showControlsView) - controlsController.get().subscribeToFavorites(selectedStructure) } controlsListingController.get().addCallback(listingCallback) @@ -297,7 +304,7 @@ class ControlsUiControllerImpl @Inject constructor ( } itemsWithStructure.sortWith(localeComparator) - val selectionItem = findSelectionItem(selectedStructure, itemsWithStructure) ?: items[0] + val selectionItem = findSelectionItem(selectedItem, itemsWithStructure) ?: items[0] controlsMetricsLogger.refreshBegin(selectionItem.uid, !keyguardStateController.isUnlocked()) @@ -307,6 +314,8 @@ class ControlsUiControllerImpl @Inject constructor ( } private fun createMenu() { + if (selectedItem !is SelectedItem.StructureItem) return + val selectedStructure = (selectedItem as SelectedItem.StructureItem).structure val items = arrayOf( context.resources.getString(R.string.controls_menu_add), context.resources.getString(R.string.controls_menu_edit) @@ -399,6 +408,8 @@ class ControlsUiControllerImpl @Inject constructor ( } private fun createListView(selected: SelectionItem) { + if (selectedItem !is SelectedItem.StructureItem) return + val selectedStructure = (selectedItem as SelectedItem.StructureItem).structure val inflater = LayoutInflater.from(context) inflater.inflate(R.layout.controls_with_favorites, parent, true) @@ -453,35 +464,44 @@ class ControlsUiControllerImpl @Inject constructor ( } } - override fun getPreferredStructure(structures: List): StructureInfo { - if (structures.isEmpty()) return EMPTY_STRUCTURE + override fun getPreferredSelectedItem(structures: List): SelectedItem { + val sp = sharedPreferences - val component = sharedPreferences.getString(PREF_COMPONENT, null)?.let { + val component = sp.getString(PREF_COMPONENT, null)?.let { ComponentName.unflattenFromString(it) } ?: EMPTY_COMPONENT - val structure = sharedPreferences.getString(PREF_STRUCTURE, "") - - return structures.firstOrNull { - component == it.componentName && structure == it.structure - } ?: structures.get(0) + val name = sp.getString(PREF_STRUCTURE_OR_APP_NAME, "")!! + val isPanel = sp.getBoolean(PREF_IS_PANEL, false) + return if (isPanel) { + SelectedItem.PanelItem(name, component) + } else { + if (structures.isEmpty()) return SelectedItem.EMPTY_SELECTION + SelectedItem.StructureItem(structures.firstOrNull { + component == it.componentName && name == it.structure + } ?: structures.get(0)) + } } - private fun updatePreferences(si: StructureInfo) { - if (si == EMPTY_STRUCTURE) return + private fun updatePreferences(si: SelectedItem) { sharedPreferences.edit() - .putString(PREF_COMPONENT, si.componentName.flattenToString()) - .putString(PREF_STRUCTURE, si.structure.toString()) - .commit() + .putString(PREF_COMPONENT, si.componentName.flattenToString()) + .putString(PREF_STRUCTURE_OR_APP_NAME, si.name.toString()) + .putBoolean(PREF_IS_PANEL, si is SelectedItem.PanelItem) + .commit() } private fun switchAppOrStructure(item: SelectionItem) { - val newSelection = allStructures.first { - it.structure == item.structure && it.componentName == item.componentName + val newSelection = if (item.isPanel) { + SelectedItem.PanelItem(item.appName, item.componentName) + } else { + SelectedItem.StructureItem(allStructures.first { + it.structure == item.structure && it.componentName == item.componentName + }) } - if (newSelection != selectedStructure) { - selectedStructure = newSelection - updatePreferences(selectedStructure) + if (newSelection != selectedItem) { + selectedItem = newSelection + updatePreferences(selectedItem) reload(parent) } } @@ -545,20 +565,37 @@ class ControlsUiControllerImpl @Inject constructor ( return row } - private fun findSelectionItem(si: StructureInfo, items: List): SelectionItem? = - items.firstOrNull { - it.componentName == si.componentName && it.structure == si.structure - } + private fun findSelectionItem(si: SelectedItem, items: List): SelectionItem? = + items.firstOrNull { it.matches(si) } } -private data class SelectionItem( +@VisibleForTesting +internal data class SelectionItem( val appName: CharSequence, val structure: CharSequence, val icon: Drawable, val componentName: ComponentName, - val uid: Int + val uid: Int, + val panelComponentName: ComponentName? ) { fun getTitle() = if (structure.isEmpty()) { appName } else { structure } + + val isPanel: Boolean = panelComponentName != null + + fun matches(selectedItem: SelectedItem): Boolean { + if (componentName != selectedItem.componentName) { + // Not the same component so they are not the same. + return false + } + if (isPanel || selectedItem is SelectedItem.PanelItem) { + // As they have the same component, if [this.isPanel] then we may be migrating from + // device controls API into panel. Want this to match, even if the selectedItem is not + // a panel. We don't want to match on app name because that can change with locale. + return true + } + // Return true if we find a structure with the correct name + return structure == (selectedItem as SelectedItem.StructureItem).structure.structure + } } private class ItemAdapter( diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt index c65bd9b4348e1..41d854969e20f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt @@ -32,6 +32,7 @@ import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.ui.ControlsUiController +import com.android.systemui.controls.ui.SelectedItem import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.ActivityStarter @@ -125,14 +126,15 @@ class DeviceControlsTile @Inject constructor( state.icon = icon if (controlsComponent.isEnabled() && hasControlsApps.get()) { if (controlsComponent.getVisibility() == AVAILABLE) { - val structureInfo = controlsComponent - .getControlsController().get().getPreferredStructure() - state.state = if (structureInfo.controls.isEmpty()) { + val selection = controlsComponent + .getControlsController().get().getPreferredSelection() + state.state = if (selection is SelectedItem.StructureItem && + selection.structure.controls.isEmpty()) { Tile.STATE_INACTIVE } else { Tile.STATE_ACTIVE } - val label = structureInfo.structure + val label = selection.name state.secondaryLabel = if (label == tileLabel) null else label } else { state.state = Tile.STATE_INACTIVE diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt index 49c7442b9708a..a86cb00b3a818 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt @@ -44,7 +44,6 @@ import org.mockito.Mock import org.mockito.Mockito.anyInt import org.mockito.Mockito.anyString import org.mockito.Mockito.mock -import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @@ -105,8 +104,8 @@ class ControlsUiControllerImplTest : SysuiTestCase() { @Test fun testGetPreferredStructure() { val structureInfo = mock(StructureInfo::class.java) - underTest.getPreferredStructure(listOf(structureInfo)) - verify(userFileManager, times(2)) + underTest.getPreferredSelectedItem(listOf(structureInfo)) + verify(userFileManager) .getSharedPreferences( fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, mode = 0, @@ -116,25 +115,30 @@ class ControlsUiControllerImplTest : SysuiTestCase() { @Test fun testGetPreferredStructure_differentUserId() { - val structureInfo = + val selectedItems = listOf( - StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList()), - StructureInfo(ComponentName.unflattenFromString("pkg/.cls2"), "b", ArrayList()), + SelectedItem.StructureItem( + StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList()) + ), + SelectedItem.StructureItem( + StructureInfo(ComponentName.unflattenFromString("pkg/.cls2"), "b", ArrayList()) + ), ) + val structures = selectedItems.map { it.structure } sharedPreferences .edit() - .putString("controls_component", structureInfo[0].componentName.flattenToString()) - .putString("controls_structure", structureInfo[0].structure.toString()) + .putString("controls_component", selectedItems[0].componentName.flattenToString()) + .putString("controls_structure", selectedItems[0].name.toString()) .commit() val differentSharedPreferences = FakeSharedPreferences() differentSharedPreferences .edit() - .putString("controls_component", structureInfo[1].componentName.flattenToString()) - .putString("controls_structure", structureInfo[1].structure.toString()) + .putString("controls_component", selectedItems[1].componentName.flattenToString()) + .putString("controls_structure", selectedItems[1].name.toString()) .commit() - val previousPreferredStructure = underTest.getPreferredStructure(structureInfo) + val previousPreferredStructure = underTest.getPreferredSelectedItem(structures) `when`( userFileManager.getSharedPreferences( @@ -146,10 +150,25 @@ class ControlsUiControllerImplTest : SysuiTestCase() { .thenReturn(differentSharedPreferences) `when`(userTracker.userId).thenReturn(1) - val currentPreferredStructure = underTest.getPreferredStructure(structureInfo) + val currentPreferredStructure = underTest.getPreferredSelectedItem(structures) - assertThat(previousPreferredStructure).isEqualTo(structureInfo[0]) - assertThat(currentPreferredStructure).isEqualTo(structureInfo[1]) + assertThat(previousPreferredStructure).isEqualTo(selectedItems[0]) + assertThat(currentPreferredStructure).isEqualTo(selectedItems[1]) assertThat(currentPreferredStructure).isNotEqualTo(previousPreferredStructure) } + + @Test + fun testGetPreferredPanel() { + val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls")) + sharedPreferences + .edit() + .putString("controls_component", panel.componentName.flattenToString()) + .putString("controls_structure", panel.appName.toString()) + .putBoolean("controls_is_panel", true) + .commit() + + val selected = underTest.getPreferredSelectedItem(emptyList()) + + assertThat(selected).isEqualTo(panel) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt new file mode 100644 index 0000000000000..57176f0eabe0f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt @@ -0,0 +1,112 @@ +package com.android.systemui.controls.ui + +import android.content.ComponentName +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.controls.controller.StructureInfo +import com.android.systemui.util.mockito.mock +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class SelectionItemTest : SysuiTestCase() { + + @Test + fun testMatchBadComponentName_false() { + val selectionItem = + SelectionItem( + appName = "app", + structure = "structure", + icon = mock(), + componentName = ComponentName("pkg", "cls"), + uid = 0, + panelComponentName = null + ) + + assertThat( + selectionItem.matches( + SelectedItem.StructureItem( + StructureInfo(ComponentName("", ""), "s", emptyList()) + ) + ) + ) + .isFalse() + assertThat(selectionItem.matches(SelectedItem.PanelItem("name", ComponentName("", "")))) + .isFalse() + } + + @Test + fun testMatchSameComponentName_panelSelected_true() { + val componentName = ComponentName("pkg", "cls") + + val selectionItem = + SelectionItem( + appName = "app", + structure = "structure", + icon = mock(), + componentName = componentName, + uid = 0, + panelComponentName = null + ) + assertThat(selectionItem.matches(SelectedItem.PanelItem("name", componentName))).isTrue() + } + + @Test + fun testMatchSameComponentName_panelSelection_true() { + val componentName = ComponentName("pkg", "cls") + + val selectionItem = + SelectionItem( + appName = "app", + structure = "structure", + icon = mock(), + componentName = componentName, + uid = 0, + panelComponentName = ComponentName("pkg", "panel") + ) + assertThat(selectionItem.matches(SelectedItem.PanelItem("name", componentName))).isTrue() + } + + @Test + fun testMatchSameComponentSameStructure_true() { + val componentName = ComponentName("pkg", "cls") + val structureName = "structure" + + val structureItem = + SelectedItem.StructureItem(StructureInfo(componentName, structureName, emptyList())) + + val selectionItem = + SelectionItem( + appName = "app", + structure = structureName, + icon = mock(), + componentName = componentName, + uid = 0, + panelComponentName = null + ) + assertThat(selectionItem.matches(structureItem)).isTrue() + } + + @Test + fun testMatchSameComponentDifferentStructure_false() { + val componentName = ComponentName("pkg", "cls") + val structureName = "structure" + + val structureItem = + SelectedItem.StructureItem(StructureInfo(componentName, structureName, emptyList())) + + val selectionItem = + SelectionItem( + appName = "app", + structure = "other", + icon = mock(), + componentName = componentName, + uid = 0, + panelComponentName = null + ) + assertThat(selectionItem.matches(structureItem)).isFalse() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt index f7b9438e6535e..e0b3125fd62a8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt @@ -40,6 +40,7 @@ import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.ui.ControlsActivity import com.android.systemui.controls.ui.ControlsUiController +import com.android.systemui.controls.ui.SelectedItem import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost @@ -118,8 +119,9 @@ class DeviceControlsTileTest : SysuiTestCase() { `when`(qsHost.context).thenReturn(spiedContext) `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger) `when`(controlsComponent.isEnabled()).thenReturn(true) - `when`(controlsController.getPreferredStructure()) - .thenReturn(StructureInfo(ComponentName("pkg", "cls"), "structure", listOf())) + `when`(controlsController.getPreferredSelection()) + .thenReturn(SelectedItem.StructureItem( + StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))) secureSettings.putInt(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 1) setupControlsComponent() @@ -226,12 +228,12 @@ class DeviceControlsTileTest : SysuiTestCase() { capture(listingCallbackCaptor) ) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) - `when`(controlsController.getPreferredStructure()).thenReturn( - StructureInfo( + `when`(controlsController.getPreferredSelection()).thenReturn( + SelectedItem.StructureItem(StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) - ) + )) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) @@ -247,8 +249,9 @@ class DeviceControlsTileTest : SysuiTestCase() { capture(listingCallbackCaptor) ) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) - `when`(controlsController.getPreferredStructure()) - .thenReturn(StructureInfo(ComponentName("pkg", "cls"), "structure", listOf())) + `when`(controlsController.getPreferredSelection()) + .thenReturn(SelectedItem.StructureItem( + StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() @@ -256,6 +259,22 @@ class DeviceControlsTileTest : SysuiTestCase() { assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE) } + @Test + fun testStateActiveIfPreferredIsPanel() { + verify(controlsListingController).observe( + any(LifecycleOwner::class.java), + capture(listingCallbackCaptor) + ) + `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) + `when`(controlsController.getPreferredSelection()) + .thenReturn(SelectedItem.PanelItem("appName", ComponentName("pkg", "cls"))) + + listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) + testableLooper.processAllMessages() + + assertThat(tile.state.state).isEqualTo(Tile.STATE_ACTIVE) + } + @Test fun testStateInactiveIfLocked() { verify(controlsListingController).observe( @@ -303,12 +322,12 @@ class DeviceControlsTileTest : SysuiTestCase() { ) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java) - `when`(controlsController.getPreferredStructure()).thenReturn( - StructureInfo( - ComponentName("pkg", "cls"), - "structure", - listOf(ControlInfo("id", "title", "subtitle", 1)) - ) + `when`(controlsController.getPreferredSelection()).thenReturn( + SelectedItem.StructureItem(StructureInfo( + ComponentName("pkg", "cls"), + "structure", + listOf(ControlInfo("id", "title", "subtitle", 1)) + )) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) @@ -334,12 +353,12 @@ class DeviceControlsTileTest : SysuiTestCase() { `when`(controlsComponent.getVisibility()) .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) `when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java) - `when`(controlsController.getPreferredStructure()).thenReturn( - StructureInfo( + `when`(controlsController.getPreferredSelection()).thenReturn( + SelectedItem.StructureItem(StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) - ) + )) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))