Source slot IDs and capacities from config XML.

Slot IDs and capacities are defined in XML now. This allowes OEMs with
greater flexibility to override how many slots and how many affordances
can be in slot on the lock screen.

Our internal, shared library, still makes hard-coded assumptions about
there only being the expected number and IDs for slots, which is okay
since that code won't necessarily be used by OEMs.

Fix: 256195304
Test: Unit tests expanded

Change-Id: Ic2752e80cdda7495d3f03085597f3b995f461bda
This commit is contained in:
Alejandro Nijamkin
2022-11-01 13:35:24 -07:00
committed by Ale Nijamkin
parent 3c410d04e6
commit 2719171200
6 changed files with 68 additions and 15 deletions

View File

@@ -804,4 +804,15 @@
<!-- Whether the device should display hotspot UI. If true, UI will display only when tethering
is available. If false, UI will never show regardless of tethering availability" -->
<bool name="config_show_wifi_tethering">true</bool>
<!-- A collection of "slots" for placing quick affordance actions on the lock screen when the
device is locked. Each item is a string consisting of two parts, separated by the ':' character.
The first part is the unique ID for the slot, it is not a human-visible name, but should still
be unique across all slots specified. The second part is the capacity and must be a positive
integer; this is how many quick affordance actions that user is allowed to add to the slot. -->
<string-array name="config_keyguardQuickAffordanceSlots" translatable="false">
<item>bottom_start:1</item>
<item>bottom_end:1</item>
</string-array>
</resources>

View File

@@ -17,6 +17,8 @@
package com.android.systemui.keyguard.data.repository
import android.content.Context
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
@@ -24,7 +26,6 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceSelectionManager
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerRepresentation
import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -39,6 +40,7 @@ import kotlinx.coroutines.launch
class KeyguardQuickAffordanceRepository
@Inject
constructor(
@Application private val appContext: Context,
@Application private val scope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val selectionManager: KeyguardQuickAffordanceSelectionManager,
@@ -61,6 +63,30 @@ constructor(
initialValue = emptyMap(),
)
private val _slotPickerRepresentations: List<KeyguardSlotPickerRepresentation> by lazy {
fun parseSlot(unparsedSlot: String): Pair<String, Int> {
val split = unparsedSlot.split(SLOT_CONFIG_DELIMITER)
check(split.size == 2)
val slotId = split[0]
val slotCapacity = split[1].toInt()
return slotId to slotCapacity
}
val unparsedSlots =
appContext.resources.getStringArray(R.array.config_keyguardQuickAffordanceSlots)
val seenSlotIds = mutableSetOf<String>()
unparsedSlots.mapNotNull { unparsedSlot ->
val (slotId, slotCapacity) = parseSlot(unparsedSlot)
check(!seenSlotIds.contains(slotId)) { "Duplicate slot \"$slotId\"!" }
seenSlotIds.add(slotId)
KeyguardSlotPickerRepresentation(
id = slotId,
maxSelectedAffordances = slotCapacity,
)
}
}
/**
* Returns a snapshot of the [KeyguardQuickAffordanceConfig] instances of the affordances at the
* slot with the given ID. The configs are sorted in descending priority order.
@@ -115,14 +141,10 @@ constructor(
* each slot and select which affordance(s) is/are installed in each slot on the keyguard.
*/
fun getSlotPickerRepresentations(): List<KeyguardSlotPickerRepresentation> {
// TODO(b/256195304): source these from a config XML file.
return listOf(
KeyguardSlotPickerRepresentation(
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
),
KeyguardSlotPickerRepresentation(
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
),
)
return _slotPickerRepresentations
}
companion object {
private const val SLOT_CONFIG_DELIMITER = ":"
}
}

View File

@@ -18,13 +18,13 @@
package com.android.systemui.keyguard.data.repository
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceSelectionManager
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerRepresentation
import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -53,6 +53,7 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
config2 = FakeKeyguardQuickAffordanceConfig("built_in:2")
underTest =
KeyguardQuickAffordanceRepository(
appContext = context,
scope = CoroutineScope(IMMEDIATE),
backgroundDispatcher = IMMEDIATE,
selectionManager = KeyguardQuickAffordanceSelectionManager(),
@@ -119,16 +120,32 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
@Test
fun getSlotPickerRepresentations() {
val slot1 = "slot1"
val slot2 = "slot2"
val slot3 = "slot3"
context.orCreateTestableResources.addOverride(
R.array.config_keyguardQuickAffordanceSlots,
arrayOf(
"$slot1:2",
"$slot2:4",
"$slot3:5",
),
)
assertThat(underTest.getSlotPickerRepresentations())
.isEqualTo(
listOf(
KeyguardSlotPickerRepresentation(
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
maxSelectedAffordances = 1,
id = slot1,
maxSelectedAffordances = 2,
),
KeyguardSlotPickerRepresentation(
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
maxSelectedAffordances = 1,
id = slot2,
maxSelectedAffordances = 4,
),
KeyguardSlotPickerRepresentation(
id = slot3,
maxSelectedAffordances = 5,
),
)
)

View File

@@ -230,6 +230,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER)
val quickAffordanceRepository =
KeyguardQuickAffordanceRepository(
appContext = context,
scope = CoroutineScope(IMMEDIATE),
backgroundDispatcher = IMMEDIATE,
selectionManager = KeyguardQuickAffordanceSelectionManager(),

View File

@@ -92,6 +92,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
val quickAffordanceRepository =
KeyguardQuickAffordanceRepository(
appContext = context,
scope = CoroutineScope(IMMEDIATE),
backgroundDispatcher = IMMEDIATE,
selectionManager = KeyguardQuickAffordanceSelectionManager(),

View File

@@ -117,6 +117,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
val quickAffordanceRepository =
KeyguardQuickAffordanceRepository(
appContext = context,
scope = CoroutineScope(IMMEDIATE),
backgroundDispatcher = IMMEDIATE,
selectionManager = KeyguardQuickAffordanceSelectionManager(),