Loading packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt +10 −3 Original line number Diff line number Diff line Loading @@ -18,10 +18,17 @@ package com.android.systemui.shared.quickaffordance.shared.model object KeyguardPreviewConstants { const val MESSAGE_ID_DEFAULT_PREVIEW = 707 const val MESSAGE_ID_HIDE_SMART_SPACE = 1111 const val KEY_HIDE_SMART_SPACE = "hide_smart_space" const val MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED = 1988 const val MESSAGE_ID_SLOT_SELECTED = 1337 const val KEY_SLOT_ID = "slot_id" const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id" const val MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES = 214 const val KEY_HIDE_SMART_SPACE = "hide_smart_space" const val KEY_HIGHLIGHT_QUICK_AFFORDANCES = "highlight_quick_affordances" const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id" const val KEY_QUICK_AFFORDANCE_ID = "quick_affordance_id" const val KEY_SLOT_ID = "slot_id" const val KEYGUARD_QUICK_AFFORDANCE_ID_NONE = "none" } packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt +9 −0 Original line number Diff line number Diff line Loading @@ -308,6 +308,15 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() { ) } @Test fun getConfig() = testScope.runTest { assertThat(underTest.getConfig(FakeCustomizationProviderClient.AFFORDANCE_1)) .isEqualTo(config1) assertThat(underTest.getConfig(FakeCustomizationProviderClient.AFFORDANCE_2)) .isEqualTo(config2) } private fun assertSelections( observed: Map<String, List<KeyguardQuickAffordanceConfig>>?, expected: Map<String, List<KeyguardQuickAffordanceConfig>>, Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt +58 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,64 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active) } @Test fun quickAffordanceAlwaysVisible_withNonNullOverrideKeyguardQuickAffordanceId() = testScope.runTest { quickAccessWallet.setState( KeyguardQuickAffordanceConfig.LockScreenState.Visible( icon = ICON, activationState = ActivationState.Active, ) ) homeControls.setState( KeyguardQuickAffordanceConfig.LockScreenState.Visible( icon = ICON, activationState = ActivationState.Active, ) ) // The default case val collectedValue = collectLastValue( underTest.quickAffordanceAlwaysVisible( KeyguardQuickAffordancePosition.BOTTOM_START, ) ) assertThat(collectedValue()) .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible assertThat(visibleModel.configKey) .isEqualTo( "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${homeControls.key}" ) assertThat(visibleModel.icon).isEqualTo(ICON) assertThat(visibleModel.icon.contentDescription) .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID)) assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active) // With override val collectedValueWithOverride = collectLastValue( underTest.quickAffordanceAlwaysVisible( position = KeyguardQuickAffordancePosition.BOTTOM_START, overrideQuickAffordanceId = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET, ) ) assertThat(collectedValueWithOverride()) .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModelWithOverride = collectedValueWithOverride() as KeyguardQuickAffordanceModel.Visible assertThat(visibleModelWithOverride.configKey) .isEqualTo( "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${quickAccessWallet.key}" ) assertThat(visibleModelWithOverride.icon).isEqualTo(ICON) assertThat(visibleModelWithOverride.icon.contentDescription) .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID)) assertThat(visibleModelWithOverride.activationState).isEqualTo(ActivationState.Active) } @Test fun select() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.keyguard import com.android.systemui.Flags /** Helper for reading or using the new picker UI flag. */ @Suppress("NOTHING_TO_INLINE") object NewPickerUiKeyguardPreview { /** Is the new picker UI enabled */ @JvmStatic inline val isEnabled get() = Flags.newPickerUi() } packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt +13 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Intent import android.os.UserHandle import android.util.LayoutDirection import com.android.systemui.Dumpable import com.android.systemui.res.R import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton Loading @@ -35,6 +34,7 @@ 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.res.R import com.android.systemui.settings.UserTracker import java.io.PrintWriter import javax.inject.Inject Loading @@ -61,10 +61,13 @@ constructor( private val remoteUserSelectionManager: KeyguardQuickAffordanceRemoteUserSelectionManager, private val userTracker: UserTracker, legacySettingSyncer: KeyguardQuickAffordanceLegacySettingSyncer, private val configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>, configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>, dumpManager: DumpManager, userHandle: UserHandle, ) { // Configs for all keyguard quick affordances, mapped by the quick affordance ID as key private val configsByAffordanceId: Map<String, KeyguardQuickAffordanceConfig> = configs.associateBy { it.key } private val userId: Flow<Int> = ConflatedCallbackFlow.conflatedCallbackFlow { val callback = Loading Loading @@ -126,7 +129,7 @@ constructor( */ fun getCurrentSelections(slotId: String): List<KeyguardQuickAffordanceConfig> { val selections = selectionManager.value.getSelections().getOrDefault(slotId, emptyList()) return configs.filter { selections.contains(it.key) } return configsByAffordanceId.values.filter { selections.contains(it.key) } } /** Loading Loading @@ -159,7 +162,7 @@ constructor( */ suspend fun getAffordancePickerRepresentations(): List<KeyguardQuickAffordancePickerRepresentation> { return configs return configsByAffordanceId.values .associateWith { config -> config.getPickerScreenState() } .filterNot { (_, pickerState) -> pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice Loading Loading @@ -226,6 +229,11 @@ constructor( } } /** Get the config of a quick affordance. */ fun getConfig(quickAffordanceId: String): KeyguardQuickAffordanceConfig? { return configsByAffordanceId[quickAffordanceId] } private inner class Dumpster : Dumpable { override fun dump(pw: PrintWriter, args: Array<out String>) { val slotPickerRepresentations = getSlotPickerRepresentations() Loading @@ -246,7 +254,7 @@ constructor( pw.println(" $slotId$selectionText (capacity = $capacity)") } pw.println("Available affordances on device:") configs.forEach { config -> configsByAffordanceId.values.forEach { config -> pw.println(" ${config.key} (\"${config.pickerName()}\")") } } Loading Loading
packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt +10 −3 Original line number Diff line number Diff line Loading @@ -18,10 +18,17 @@ package com.android.systemui.shared.quickaffordance.shared.model object KeyguardPreviewConstants { const val MESSAGE_ID_DEFAULT_PREVIEW = 707 const val MESSAGE_ID_HIDE_SMART_SPACE = 1111 const val KEY_HIDE_SMART_SPACE = "hide_smart_space" const val MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED = 1988 const val MESSAGE_ID_SLOT_SELECTED = 1337 const val KEY_SLOT_ID = "slot_id" const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id" const val MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES = 214 const val KEY_HIDE_SMART_SPACE = "hide_smart_space" const val KEY_HIGHLIGHT_QUICK_AFFORDANCES = "highlight_quick_affordances" const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id" const val KEY_QUICK_AFFORDANCE_ID = "quick_affordance_id" const val KEY_SLOT_ID = "slot_id" const val KEYGUARD_QUICK_AFFORDANCE_ID_NONE = "none" }
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt +9 −0 Original line number Diff line number Diff line Loading @@ -308,6 +308,15 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() { ) } @Test fun getConfig() = testScope.runTest { assertThat(underTest.getConfig(FakeCustomizationProviderClient.AFFORDANCE_1)) .isEqualTo(config1) assertThat(underTest.getConfig(FakeCustomizationProviderClient.AFFORDANCE_2)) .isEqualTo(config2) } private fun assertSelections( observed: Map<String, List<KeyguardQuickAffordanceConfig>>?, expected: Map<String, List<KeyguardQuickAffordanceConfig>>, Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt +58 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,64 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active) } @Test fun quickAffordanceAlwaysVisible_withNonNullOverrideKeyguardQuickAffordanceId() = testScope.runTest { quickAccessWallet.setState( KeyguardQuickAffordanceConfig.LockScreenState.Visible( icon = ICON, activationState = ActivationState.Active, ) ) homeControls.setState( KeyguardQuickAffordanceConfig.LockScreenState.Visible( icon = ICON, activationState = ActivationState.Active, ) ) // The default case val collectedValue = collectLastValue( underTest.quickAffordanceAlwaysVisible( KeyguardQuickAffordancePosition.BOTTOM_START, ) ) assertThat(collectedValue()) .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible assertThat(visibleModel.configKey) .isEqualTo( "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${homeControls.key}" ) assertThat(visibleModel.icon).isEqualTo(ICON) assertThat(visibleModel.icon.contentDescription) .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID)) assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active) // With override val collectedValueWithOverride = collectLastValue( underTest.quickAffordanceAlwaysVisible( position = KeyguardQuickAffordancePosition.BOTTOM_START, overrideQuickAffordanceId = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET, ) ) assertThat(collectedValueWithOverride()) .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModelWithOverride = collectedValueWithOverride() as KeyguardQuickAffordanceModel.Visible assertThat(visibleModelWithOverride.configKey) .isEqualTo( "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${quickAccessWallet.key}" ) assertThat(visibleModelWithOverride.icon).isEqualTo(ICON) assertThat(visibleModelWithOverride.icon.contentDescription) .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID)) assertThat(visibleModelWithOverride.activationState).isEqualTo(ActivationState.Active) } @Test fun select() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.keyguard import com.android.systemui.Flags /** Helper for reading or using the new picker UI flag. */ @Suppress("NOTHING_TO_INLINE") object NewPickerUiKeyguardPreview { /** Is the new picker UI enabled */ @JvmStatic inline val isEnabled get() = Flags.newPickerUi() }
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt +13 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Intent import android.os.UserHandle import android.util.LayoutDirection import com.android.systemui.Dumpable import com.android.systemui.res.R import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton Loading @@ -35,6 +34,7 @@ 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.res.R import com.android.systemui.settings.UserTracker import java.io.PrintWriter import javax.inject.Inject Loading @@ -61,10 +61,13 @@ constructor( private val remoteUserSelectionManager: KeyguardQuickAffordanceRemoteUserSelectionManager, private val userTracker: UserTracker, legacySettingSyncer: KeyguardQuickAffordanceLegacySettingSyncer, private val configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>, configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>, dumpManager: DumpManager, userHandle: UserHandle, ) { // Configs for all keyguard quick affordances, mapped by the quick affordance ID as key private val configsByAffordanceId: Map<String, KeyguardQuickAffordanceConfig> = configs.associateBy { it.key } private val userId: Flow<Int> = ConflatedCallbackFlow.conflatedCallbackFlow { val callback = Loading Loading @@ -126,7 +129,7 @@ constructor( */ fun getCurrentSelections(slotId: String): List<KeyguardQuickAffordanceConfig> { val selections = selectionManager.value.getSelections().getOrDefault(slotId, emptyList()) return configs.filter { selections.contains(it.key) } return configsByAffordanceId.values.filter { selections.contains(it.key) } } /** Loading Loading @@ -159,7 +162,7 @@ constructor( */ suspend fun getAffordancePickerRepresentations(): List<KeyguardQuickAffordancePickerRepresentation> { return configs return configsByAffordanceId.values .associateWith { config -> config.getPickerScreenState() } .filterNot { (_, pickerState) -> pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice Loading Loading @@ -226,6 +229,11 @@ constructor( } } /** Get the config of a quick affordance. */ fun getConfig(quickAffordanceId: String): KeyguardQuickAffordanceConfig? { return configsByAffordanceId[quickAffordanceId] } private inner class Dumpster : Dumpable { override fun dump(pw: PrintWriter, args: Array<out String>) { val slotPickerRepresentations = getSlotPickerRepresentations() Loading @@ -246,7 +254,7 @@ constructor( pw.println(" $slotId$selectionText (capacity = $capacity)") } pw.println("Available affordances on device:") configs.forEach { config -> configsByAffordanceId.values.forEach { config -> pw.println(" ${config.key} (\"${config.pickerName()}\")") } } Loading