Distinguish between selected panel or structure

To pave the way, we add a SelectedItem that could contain a
StructureInfo or information for a Panel.

In particular, a Panel points to the ComponentName of the
ControlsProviderService (and not of the activity) for backwards
compatibility and migration. As we still need to match the SelectionInfo
that has the activity information, this is not an issue.

Also, add persistence for the panel using the same keys (and an extra
boolean) for better migration.

Test: atest com.android.systemui.controls
Test: atest DeviceControlsTile
Fixes: 258442632
Change-Id: I544f5cdcb4fdfe0488df05d686173ed3bb709b8e
This commit is contained in:
Fabian Kozynski
2022-11-10 15:48:00 -05:00
parent b0614930ea
commit 82587b1a42
9 changed files with 321 additions and 91 deletions

View File

@@ -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].

View File

@@ -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<out String>) {

View File

@@ -31,4 +31,9 @@ data class StructureInfo(
val componentName: ComponentName,
val structure: CharSequence,
val controls: List<ControlInfo>
)
) {
companion object {
val EMPTY_COMPONENT = ComponentName("", "")
val EMPTY_STRUCTURE = StructureInfo(EMPTY_COMPONENT, "", mutableListOf())
}
}

View File

@@ -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>): StructureInfo
fun getPreferredSelectedItem(structures: List<StructureInfo>): 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)
}
}

View File

@@ -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<ControlInfo>()
)
}
private var selectedStructure: StructureInfo = EMPTY_STRUCTURE
private var selectedItem: SelectedItem = SelectedItem.EMPTY_SELECTION
private lateinit var allStructures: List<StructureInfo>
private val controlsById = mutableMapOf<ControlKey, ControlWithState>()
private val controlViewsById = mutableMapOf<ControlKey, ControlViewHolder>()
private lateinit var parent: ViewGroup
private lateinit var lastItems: List<SelectionItem>
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<Boolean> {
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<ControlsServiceInfo>) {
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>): StructureInfo {
if (structures.isEmpty()) return EMPTY_STRUCTURE
override fun getPreferredSelectedItem(structures: List<StructureInfo>): 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>): SelectionItem? =
items.firstOrNull {
it.componentName == si.componentName && it.structure == si.structure
}
private fun findSelectionItem(si: SelectedItem, items: List<SelectionItem>): 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(

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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()
}
}

View File

@@ -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))