Merge "Modify quick affordances view model" into main
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt b/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt
index fd04580..32ee209 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2.kt
@@ -51,8 +51,8 @@
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.take
class KeyguardQuickAffordancePickerViewModel2
@AssistedInject
@@ -80,12 +80,31 @@
started = SharingStarted.WhileSubscribed(),
initialValue = "",
)
- private val _previewingQuickAffordances = MutableStateFlow<Map<String, String>>(emptyMap())
- val previewingQuickAffordances: Flow<Map<String, String>> =
- _previewingQuickAffordances.asStateFlow()
+ private val overridingQuickAffordances = MutableStateFlow<Map<String, String>>(emptyMap())
+ private val selectedQuickAffordancesGroupBySlotId =
+ quickAffordanceInteractor.selections.map {
+ it.groupBy { selectionModel -> selectionModel.slotId }
+ }
+
+ val previewingQuickAffordances =
+ combine(
+ quickAffordanceInteractor.slots,
+ overridingQuickAffordances,
+ selectedQuickAffordancesGroupBySlotId,
+ ) { slots, overridingQuickAffordances, selectedQuickAffordancesGroupBySlotId ->
+ slots.associate { slot ->
+ val selectedAffordanceId =
+ overridingQuickAffordances[slot.id]
+ ?: selectedQuickAffordancesGroupBySlotId[slot.id]
+ ?.firstOrNull()
+ ?.affordanceId
+ ?: KEYGUARD_QUICK_AFFORDANCE_ID_NONE
+ slot.id to selectedAffordanceId
+ }
+ }
fun resetPreview() {
- _previewingQuickAffordances.tryEmit(emptyMap())
+ overridingQuickAffordances.tryEmit(emptyMap())
_selectedSlotId.tryEmit(SLOT_ID_BOTTOM_START)
}
@@ -94,21 +113,13 @@
combine(
quickAffordanceInteractor.slots,
quickAffordanceInteractor.affordances,
- quickAffordanceInteractor.selections,
previewingQuickAffordances,
selectedSlotId,
- ) { slots, affordances, selections, selectedQuickAffordances, selectedSlotId ->
+ ) { slots, affordances, previewingQuickAffordances, selectedSlotId ->
slots.associate { slot ->
- val selectedAffordanceIds =
- selectedQuickAffordances[slot.id]?.let { setOf(it) }
- ?: selections
- .filter { selection -> selection.slotId == slot.id }
- .map { selection -> selection.affordanceId }
- .toSet()
+ val selectedAffordanceId = previewingQuickAffordances[slot.id]
val selectedAffordances =
- affordances.filter { affordance ->
- selectedAffordanceIds.contains(affordance.id)
- }
+ affordances.filter { affordance -> selectedAffordanceId == affordance.id }
val isSelected = selectedSlotId == slot.id
slot.id to
@@ -160,31 +171,15 @@
}
}
- /**
- * The set of IDs of the currently-selected affordances. These change with user selection of new
- * or different affordances in the currently-selected slot or when slot selection changes.
- */
- private val selectedAffordanceIds: Flow<Set<String>> =
- combine(quickAffordanceInteractor.selections, selectedSlotId) { selections, selectedSlotId
- ->
- selections
- .filter { selection -> selection.slotId == selectedSlotId }
- .map { selection -> selection.affordanceId }
- .toSet()
- }
- .shareIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), replay = 1)
-
/** The list of all available quick affordances for the selected slot. */
val quickAffordances: Flow<List<OptionItemViewModel2<Icon>>> =
quickAffordanceInteractor.affordances.map { affordances ->
val isNoneSelected =
- combine(selectedSlotId, previewingQuickAffordances, selectedAffordanceIds) {
+ combine(selectedSlotId, previewingQuickAffordances) {
selectedSlotId,
- selectedQuickAffordances,
- selectedAffordanceIds ->
- selectedQuickAffordances[selectedSlotId]?.let {
- it == KEYGUARD_QUICK_AFFORDANCE_ID_NONE
- } ?: selectedAffordanceIds.isEmpty()
+ previewingQuickAffordances ->
+ previewingQuickAffordances[selectedSlotId] ==
+ KEYGUARD_QUICK_AFFORDANCE_ID_NONE
}
.stateIn(viewModelScope)
listOf(
@@ -196,10 +191,10 @@
if (!isSelected) {
{
val newMap =
- _previewingQuickAffordances.value.toMutableMap().apply {
+ overridingQuickAffordances.value.toMutableMap().apply {
put(selectedSlotId, KEYGUARD_QUICK_AFFORDANCE_ID_NONE)
}
- _previewingQuickAffordances.tryEmit(newMap)
+ overridingQuickAffordances.tryEmit(newMap)
}
} else {
null
@@ -210,14 +205,10 @@
affordances.map { affordance ->
val affordanceIcon = getAffordanceIcon(affordance.iconResourceId)
val isSelectedFlow: StateFlow<Boolean> =
- combine(
+ combine(selectedSlotId, previewingQuickAffordances) {
selectedSlotId,
- previewingQuickAffordances,
- selectedAffordanceIds,
- ) { selectedSlotId, selectedQuickAffordances, selectedAffordanceIds ->
- selectedQuickAffordances[selectedSlotId]?.let {
- it == affordance.id
- } ?: selectedAffordanceIds.contains(affordance.id)
+ previewingQuickAffordances ->
+ previewingQuickAffordances[selectedSlotId] == affordance.id
}
.stateIn(viewModelScope)
OptionItemViewModel2<Icon>(
@@ -235,10 +226,10 @@
if (!isSelected) {
{
val newMap =
- _previewingQuickAffordances.value
+ overridingQuickAffordances.value
.toMutableMap()
.apply { put(selectedSlotId, affordance.id) }
- _previewingQuickAffordances.tryEmit(newMap)
+ overridingQuickAffordances.tryEmit(newMap)
}
} else {
null
@@ -267,12 +258,20 @@
}
val onApply: Flow<(suspend () -> Unit)?> =
- previewingQuickAffordances.map {
- if (it.isEmpty()) {
- null
- } else {
+ combine(overridingQuickAffordances, selectedQuickAffordancesGroupBySlotId) {
+ overridingQuickAffordances,
+ selectedQuickAffordancesGroupBySlotId ->
+ // If all overridingQuickAffordances are same as the selected quick affordances, it is
+ // not yet edited
+ val isQuickAffordancesEdited =
+ (!overridingQuickAffordances.all { (slotId, overridingQuickAffordanceId) ->
+ selectedQuickAffordancesGroupBySlotId[slotId]?.find {
+ it.affordanceId == overridingQuickAffordanceId
+ } != null
+ })
+ if (isQuickAffordancesEdited) {
{
- it.forEach { entry ->
+ overridingQuickAffordances.forEach { entry ->
val slotId = entry.key
val affordanceId = entry.value
if (slotId == KEYGUARD_QUICK_AFFORDANCE_ID_NONE) {
@@ -283,9 +282,15 @@
affordanceId = affordanceId,
)
}
+ // Suspend until the next selectedQuickAffordancesGroupBySlotId update
+ this.selectedQuickAffordancesGroupBySlotId.take(1).collect {
+ return@collect
+ }
logger.logShortcutApplied(shortcut = affordanceId, shortcutSlotId = slotId)
}
}
+ } else {
+ null
}
}
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt
index a7efc45..7053340 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/KeyguardQuickAffordancePickerViewModel2Test.kt
@@ -26,6 +26,7 @@
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants
import com.android.themepicker.R
import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
@@ -123,7 +124,15 @@
val quickAffordances = collectLastValue(underTest.quickAffordances)
// Default selectedQuickAffordances is an empty map
- assertThat(previewingQuickAffordances()).isEqualTo(emptyMap<String, String>())
+ assertThat(previewingQuickAffordances())
+ .isEqualTo(
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
+ KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
+ KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE,
+ )
+ )
// Click on quick affordance 1 when selected slot ID is bottom_start
val onClickAffordance1 =
@@ -133,7 +142,9 @@
.isEqualTo(
mapOf(
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
- FakeCustomizationProviderClient.AFFORDANCE_1
+ FakeCustomizationProviderClient.AFFORDANCE_1,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
+ KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE,
)
)
@@ -154,7 +165,15 @@
)
underTest.resetPreview()
- assertThat(previewingQuickAffordances()).isEqualTo(emptyMap<String, String>())
+ assertThat(previewingQuickAffordances())
+ .isEqualTo(
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
+ KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
+ KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE,
+ )
+ )
}
@Test