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:
@@ -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].
|
||||
|
||||
@@ -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>) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user