summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt57
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt64
11 files changed, 331 insertions, 28 deletions
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
index 08ee60204178..a3f40d47cc3f 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
@@ -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"
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 8e109b4aab20..c85cd662dac6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -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>>,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 75c0d3b60ecb..ad07c1c1b88f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -426,6 +426,64 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
}
@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 {
overrideResource(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt b/packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt
new file mode 100644
index 000000000000..7e09a108ea40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt
@@ -0,0 +1,29 @@
+/*
+ * 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()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index 698328ecd7fb..d49550ef4c83 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -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
@@ -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
@@ -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 =
@@ -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) }
}
/**
@@ -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
@@ -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()
@@ -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()}\")")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 0682d8777107..2af95f20c7d7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -53,6 +53,7 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.KeyguardStateController
import dagger.Lazy
@@ -142,14 +143,18 @@ constructor(
*
* This is useful for experiences like the lock screen preview mode, where the affordances must
* always be visible.
+ *
+ * @param overrideQuickAffordanceId If null, return the currently-set quick affordance;
+ * otherwise, override and return the correspondent [KeyguardQuickAffordanceModel].
*/
suspend fun quickAffordanceAlwaysVisible(
position: KeyguardQuickAffordancePosition,
+ overrideQuickAffordanceId: String? = null,
): Flow<KeyguardQuickAffordanceModel> {
return if (isFeatureDisabledByDevicePolicy()) {
flowOf(KeyguardQuickAffordanceModel.Hidden)
} else {
- quickAffordanceInternal(position)
+ quickAffordanceInternal(position, overrideQuickAffordanceId)
}
}
@@ -299,12 +304,24 @@ constructor(
}
private fun quickAffordanceInternal(
- position: KeyguardQuickAffordancePosition
+ position: KeyguardQuickAffordancePosition,
+ overrideAffordanceId: String? = null,
): Flow<KeyguardQuickAffordanceModel> =
repository
.get()
.selections
- .map { it[position.toSlotId()] ?: emptyList() }
+ .map { selections ->
+ val overrideQuickAffordanceConfigs =
+ overrideAffordanceId?.let {
+ if (it == KEYGUARD_QUICK_AFFORDANCE_ID_NONE) {
+ emptyList()
+ } else {
+ val config = repository.get().getConfig(it)
+ listOfNotNull(config)
+ }
+ }
+ overrideQuickAffordanceConfigs ?: selections[position.toSlotId()] ?: emptyList()
+ }
.flatMapLatest { configs -> combinedConfigs(position, configs) }
private fun combinedConfigs(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
index 2581b595d812..1bbe84383e48 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
@@ -16,7 +16,8 @@
package com.android.systemui.keyguard.shared.quickaffordance
-import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
/** Enumerates all possible positions for quick affordances that can appear on the lock-screen. */
enum class KeyguardQuickAffordancePosition {
@@ -25,8 +26,19 @@ enum class KeyguardQuickAffordancePosition {
fun toSlotId(): String {
return when (this) {
- BOTTOM_START -> KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
- BOTTOM_END -> KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END
+ BOTTOM_START -> SLOT_ID_BOTTOM_START
+ BOTTOM_END -> SLOT_ID_BOTTOM_END
}
}
+
+ companion object {
+
+ /** If the slot ID does not match any string, return null. */
+ fun parseKeyguardQuickAffordancePosition(slotId: String): KeyguardQuickAffordancePosition? =
+ when (slotId) {
+ SLOT_ID_BOTTOM_START -> BOTTOM_START
+ SLOT_ID_BOTTOM_END -> BOTTOM_END
+ else -> null
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 6031ef60e1be..51ce3556ffbd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -275,6 +275,15 @@ constructor(
}
}
+ fun onStartCustomizingQuickAffordances(
+ initiallySelectedSlotId: String?,
+ ) {
+ quickAffordancesCombinedViewModel.enablePreviewMode(
+ initiallySelectedSlotId = initiallySelectedSlotId,
+ shouldHighlightSelectedAffordance = true,
+ )
+ }
+
fun onSlotSelected(slotId: String) {
if (KeyguardBottomAreaRefactor.isEnabled) {
quickAffordancesCombinedViewModel.onPreviewSlotSelected(slotId = slotId)
@@ -283,6 +292,21 @@ constructor(
}
}
+ fun onPreviewQuickAffordanceSelected(slotId: String, quickAffordanceId: String) {
+ quickAffordancesCombinedViewModel.onPreviewQuickAffordanceSelected(
+ slotId,
+ quickAffordanceId,
+ )
+ }
+
+ fun onDefaultPreview() {
+ quickAffordancesCombinedViewModel.onClearPreviewQuickAffordances()
+ quickAffordancesCombinedViewModel.enablePreviewMode(
+ initiallySelectedSlotId = null,
+ shouldHighlightSelectedAffordance = false,
+ )
+ }
+
fun destroy() {
isDestroyed = true
lockscreenSmartspaceController.disconnect()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
index 0532ee285d1d..a6108c45a479 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
@@ -31,7 +31,16 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_QUICK_AFFORDANCE_ID
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_SLOT_ID
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_DEFAULT_PREVIEW
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_HIDE_SMART_SPACE
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_SLOT_SELECTED
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES
import com.android.systemui.util.kotlin.logD
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -59,7 +68,7 @@ constructor(
return try {
val renderer =
if (Flags.lockscreenPreviewRendererCreateOnMainThread()) {
- runBlocking ("$TAG#previewRendererFactory.create", mainDispatcher) {
+ runBlocking("$TAG#previewRendererFactory.create", mainDispatcher) {
previewRendererFactory.create(request)
}
} else {
@@ -157,16 +166,35 @@ class PreviewLifecycleObserver(
}
when (message.what) {
- KeyguardPreviewConstants.MESSAGE_ID_SLOT_SELECTED -> {
- message.data.getString(KeyguardPreviewConstants.KEY_SLOT_ID)?.let { slotId ->
+ MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES -> {
+ checkNotNull(renderer)
+ .onStartCustomizingQuickAffordances(
+ initiallySelectedSlotId =
+ message.data.getString(KEY_INITIALLY_SELECTED_SLOT_ID)
+ ?: SLOT_ID_BOTTOM_START
+ )
+ }
+ MESSAGE_ID_SLOT_SELECTED -> {
+ message.data.getString(KEY_SLOT_ID)?.let { slotId ->
checkNotNull(renderer).onSlotSelected(slotId = slotId)
}
}
- KeyguardPreviewConstants.MESSAGE_ID_HIDE_SMART_SPACE -> {
- checkNotNull(renderer)
- .hideSmartspace(
- message.data.getBoolean(KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE)
- )
+ MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED -> {
+ val slotId = message.data.getString(KEY_SLOT_ID)
+ val quickAffordanceId = message.data.getString(KEY_QUICK_AFFORDANCE_ID)
+ if (slotId != null && quickAffordanceId != null) {
+ checkNotNull(renderer)
+ .onPreviewQuickAffordanceSelected(
+ slotId = slotId,
+ quickAffordanceId = quickAffordanceId,
+ )
+ }
+ }
+ MESSAGE_ID_DEFAULT_PREVIEW -> {
+ checkNotNull(renderer).onDefaultPreview()
+ }
+ MESSAGE_ID_HIDE_SMART_SPACE -> {
+ checkNotNull(renderer).hideSmartspace(message.data.getBoolean(KEY_HIDE_SMART_SPACE))
}
else -> checkNotNull(onDestroy).invoke(this)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index 2426f9745885..c885c9a5a29b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import androidx.annotation.VisibleForTesting
import com.android.app.tracing.FlowTracing.traceEmissionCount
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.NewPickerUiKeyguardPreview
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -29,6 +30,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -164,13 +166,36 @@ constructor(
.map { alpha -> alpha >= AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD }
.distinctUntilChanged()
+ private val previewAffordances =
+ MutableStateFlow<Map<KeyguardQuickAffordancePosition, String>>(emptyMap())
+
/** An observable for the view-model of the "start button" quick affordance. */
val startButton: Flow<KeyguardQuickAffordanceViewModel> =
- button(KeyguardQuickAffordancePosition.BOTTOM_START)
+ if (NewPickerUiKeyguardPreview.isEnabled) {
+ previewAffordances.flatMapLatestConflated {
+ button(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ overrideQuickAffordanceId = it[KeyguardQuickAffordancePosition.BOTTOM_START],
+ )
+ }
+ } else {
+ button(
+ KeyguardQuickAffordancePosition.BOTTOM_START,
+ )
+ }
/** An observable for the view-model of the "end button" quick affordance. */
val endButton: Flow<KeyguardQuickAffordanceViewModel> =
- button(KeyguardQuickAffordancePosition.BOTTOM_END)
+ if (NewPickerUiKeyguardPreview.isEnabled) {
+ previewAffordances.flatMapLatestConflated {
+ button(
+ position = KeyguardQuickAffordancePosition.BOTTOM_END,
+ overrideQuickAffordanceId = it[KeyguardQuickAffordancePosition.BOTTOM_END],
+ )
+ }
+ } else {
+ button(KeyguardQuickAffordancePosition.BOTTOM_END)
+ }
/**
* Notifies that a slot with the given ID has been selected in the preview experience that is
@@ -183,6 +208,28 @@ constructor(
}
/**
+ * Notifies to preview an affordance at a given slot ID. This is ignored for the real lock
+ * screen experience.
+ */
+ fun onPreviewQuickAffordanceSelected(slotId: String, affordanceId: String) {
+ val position =
+ KeyguardQuickAffordancePosition.parseKeyguardQuickAffordancePosition(slotId) ?: return
+ previewAffordances.value =
+ previewAffordances.value.toMutableMap().let {
+ it[position] = affordanceId
+ HashMap(it)
+ }
+ }
+
+ /**
+ * Notifies to clear up the preview affordances map. This is ignored for the real lock screen
+ * experience.
+ */
+ fun onClearPreviewQuickAffordances() {
+ previewAffordances.value = emptyMap()
+ }
+
+ /**
* Puts this view-model in "preview mode", which means it's being used for UI that is rendering
* the lock screen preview in wallpaper picker / settings and not the real experience on the
* lock screen.
@@ -207,14 +254,16 @@ constructor(
}
private fun button(
- position: KeyguardQuickAffordancePosition
+ position: KeyguardQuickAffordancePosition,
+ overrideQuickAffordanceId: String? = null,
): Flow<KeyguardQuickAffordanceViewModel> {
return previewMode
.flatMapLatest { previewMode ->
combine(
if (previewMode.isInPreviewMode) {
quickAffordanceInteractor.quickAffordanceAlwaysVisible(
- position = position
+ position = position,
+ overrideQuickAffordanceId = overrideQuickAffordanceId,
)
} else {
quickAffordanceInteractor.quickAffordance(position = position)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index 24bea2ce51c7..73b9f5783004 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import android.app.admin.DevicePolicyManager
import android.content.Intent
import android.os.UserHandle
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
@@ -402,6 +403,67 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(com.android.systemui.Flags.FLAG_NEW_PICKER_UI)
+ fun startButton_inPreviewMode_onPreviewQuickAffordanceSelected() =
+ testScope.runTest {
+ underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
+ underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, true)
+
+ repository.setKeyguardShowing(false)
+ val latest = collectLastValue(underTest.startButton)
+
+ val icon: Icon = mock()
+ val testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ isActivated = true,
+ icon = icon,
+ canShowWhileLocked = false,
+ intent = null,
+ slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(),
+ )
+ val defaultConfigKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ // Set up the quick access wallet config
+ val quickAccessWalletAffordanceConfigKey =
+ quickAccessWalletAffordanceConfig
+ .apply {
+ onTriggeredResult =
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity(
+ intent = Intent("action"),
+ canShowWhileLocked = false,
+ )
+ setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = icon,
+ activationState = ActivationState.Active,
+ )
+ )
+ }
+ .let {
+ KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId() +
+ "::${quickAccessWalletAffordanceConfig.key}"
+ }
+
+ // onPreviewQuickAffordanceSelected should trigger the override with the quick access
+ // wallet quick affordance
+ underTest.onPreviewQuickAffordanceSelected(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET,
+ )
+ Truth.assertThat(latest()?.configKey).isEqualTo(quickAccessWalletAffordanceConfigKey)
+
+ // onClearPreviewQuickAffordances should make the default quick affordance shows again
+ underTest.onClearPreviewQuickAffordances()
+ Truth.assertThat(latest()?.configKey).isEqualTo(defaultConfigKey)
+ }
+
+ @Test
fun startButton_inPreviewMode_visibleEvenWhenKeyguardNotShowing() =
testScope.runTest {
underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
@@ -445,7 +507,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
}
@Test
- fun endButton_inHiglightedPreviewMode_dimmedWhenOtherIsSelected() =
+ fun endButton_inHighlightedPreviewMode_dimmedWhenOtherIsSelected() =
testScope.runTest {
underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, true)