Disable need to long-press lockscreen shortcuts when device is docked
Bug: b/277761993
Test: atest KeyguardQuickAffordanceInteractorTest
Change-Id: I91efaabeb5cd8adfdfeb6b0ce533827cd666f11c
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b95a149..3b03dd7 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -265,6 +265,7 @@
"tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt",
// Keyguard helper
"tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt",
+ "tests/src/com/android/systemui/dock/DockManagerFake.java",
"tests/src/com/android/systemui/dump/LogBufferHelper.kt",
"tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java",
"tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt",
diff --git a/packages/SystemUI/src/com/android/systemui/dock/DockManagerExtensions.kt b/packages/SystemUI/src/com/android/systemui/dock/DockManagerExtensions.kt
new file mode 100644
index 0000000..4dbb32d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dock/DockManagerExtensions.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.dock
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Retrieves whether or not the device is docked according to DockManager. Emits a starting value
+ * of isDocked.
+ */
+fun DockManager.retrieveIsDocked(): Flow<Boolean> =
+ ConflatedCallbackFlow.conflatedCallbackFlow {
+ val callback = DockManager.DockEventListener { trySend(isDocked) }
+ addListener(callback)
+ trySend(isDocked)
+
+ awaitClose { removeListener(callback) }
+ }
\ No newline at end of file
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 8448b80..8e65c4d 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
@@ -27,6 +27,8 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
+import com.android.systemui.dock.DockManager
+import com.android.systemui.dock.retrieveIsDocked
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
@@ -71,6 +73,7 @@
private val launchAnimator: DialogLaunchAnimator,
private val logger: KeyguardQuickAffordancesMetricsLogger,
private val devicePolicyManager: DevicePolicyManager,
+ private val dockManager: DockManager,
@Background private val backgroundDispatcher: CoroutineDispatcher,
) {
private val isUsingRepository: Boolean
@@ -81,8 +84,12 @@
*
* If `false`, the UI goes back to using single taps.
*/
- val useLongPress: Boolean
- get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
+ fun useLongPress(): Flow<Boolean> =
+ if (featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)) {
+ dockManager.retrieveIsDocked().map { !it }
+ } else {
+ flowOf(false)
+ }
/** Returns an observable for the quick affordance at the given position. */
suspend fun quickAffordance(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 2d83be95..62a1a9e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -184,7 +184,8 @@
bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged(),
areQuickAffordancesFullyOpaque,
selectedPreviewSlotId,
- ) { model, animateReveal, isFullyOpaque, selectedPreviewSlotId ->
+ quickAffordanceInteractor.useLongPress(),
+ ) { model, animateReveal, isFullyOpaque, selectedPreviewSlotId, useLongPress ->
val slotId = position.toSlotId()
val isSelected = selectedPreviewSlotId == slotId
model.toViewModel(
@@ -200,6 +201,7 @@
!isSelected,
forceInactive = previewMode.isInPreviewMode,
slotId = slotId,
+ useLongPress = useLongPress,
)
}
.distinctUntilChanged()
@@ -213,6 +215,7 @@
isDimmed: Boolean,
forceInactive: Boolean,
slotId: String,
+ useLongPress: Boolean,
): KeyguardQuickAffordanceViewModel {
return when (this) {
is KeyguardQuickAffordanceModel.Visible ->
@@ -231,7 +234,7 @@
isClickable = isClickable,
isActivated = !forceInactive && activationState is ActivationState.Active,
isSelected = isSelected,
- useLongPress = quickAffordanceInteractor.useLongPress,
+ useLongPress = useLongPress,
isDimmed = isDimmed,
slotId = slotId,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 4daecd9..9cf988e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -33,6 +33,7 @@
import com.android.systemui.SystemUIAppComponentFactoryBase
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.dock.DockManagerFake
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
@@ -94,6 +95,8 @@
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
+ private lateinit var dockManager: DockManagerFake
+
private lateinit var underTest: CustomizationProvider
private lateinit var testScope: TestScope
@@ -104,6 +107,8 @@
whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
+ dockManager = DockManagerFake()
+
underTest = CustomizationProvider()
val testDispatcher = UnconfinedTestDispatcher()
testScope = TestScope(testDispatcher)
@@ -188,6 +193,7 @@
launchAnimator = launchAnimator,
logger = logger,
devicePolicyManager = devicePolicyManager,
+ dockManager = dockManager,
backgroundDispatcher = testDispatcher,
)
underTest.previewManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index 46c623a..a75e11a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dock.DockManagerFake
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
@@ -237,6 +238,7 @@
@JvmField @Parameter(3) var needsToUnlockFirst: Boolean = false
@JvmField @Parameter(4) var startActivity: Boolean = false
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
+ private lateinit var dockManager: DockManagerFake
private lateinit var userTracker: UserTracker
@Before
@@ -247,6 +249,7 @@
userTracker = FakeUserTracker()
homeControls =
FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS)
+ dockManager = DockManagerFake()
val quickAccessWallet =
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
@@ -335,6 +338,7 @@
launchAnimator = launchAnimator,
logger = logger,
devicePolicyManager = devicePolicyManager,
+ dockManager = dockManager,
backgroundDispatcher = testDispatcher,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 6e21c00..4b7c641 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -29,6 +29,8 @@
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dock.DockManager
+import com.android.systemui.dock.DockManagerFake
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
@@ -61,6 +63,7 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -93,6 +96,7 @@
private lateinit var quickAccessWallet: FakeKeyguardQuickAffordanceConfig
private lateinit var qrCodeScanner: FakeKeyguardQuickAffordanceConfig
private lateinit var featureFlags: FakeFeatureFlags
+ private lateinit var dockManager: DockManagerFake
@Before
fun setUp() {
@@ -112,6 +116,8 @@
val testDispatcher = StandardTestDispatcher()
testScope = TestScope(testDispatcher)
+ dockManager = DockManagerFake()
+
val localUserSelectionManager =
KeyguardQuickAffordanceLocalUserSelectionManager(
context = context,
@@ -192,6 +198,7 @@
launchAnimator = launchAnimator,
logger = logger,
devicePolicyManager = devicePolicyManager,
+ dockManager = dockManager,
backgroundDispatcher = testDispatcher,
)
}
@@ -590,6 +597,46 @@
}
@Test
+ fun useLongPress_whenDocked_isFalse() =
+ testScope.runTest {
+ featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
+ dockManager.setIsDocked(true)
+
+ val useLongPress by collectLastValue(underTest.useLongPress())
+
+ assertThat(useLongPress).isFalse()
+ }
+
+ @Test
+ fun useLongPress_whenNotDocked_isTrue() =
+ testScope.runTest {
+ featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
+ dockManager.setIsDocked(false)
+
+ val useLongPress by collectLastValue(underTest.useLongPress())
+
+ assertThat(useLongPress).isTrue()
+ }
+
+ @Test
+ fun useLongPress_whenNotDocked_isTrue_changedTo_whenDocked_isFalse() =
+ testScope.runTest {
+ featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
+ dockManager.setIsDocked(false)
+ val firstUseLongPress by collectLastValue (underTest.useLongPress())
+ runCurrent()
+
+ assertThat(firstUseLongPress).isTrue()
+
+ dockManager.setIsDocked(true)
+ dockManager.setDockEvent(DockManager.STATE_DOCKED)
+ val secondUseLongPress by collectLastValue(underTest.useLongPress())
+ runCurrent()
+
+ assertThat(secondUseLongPress).isFalse()
+ }
+
+ @Test
fun unselect_all() =
testScope.runTest {
featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 2361c59..5eec8a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dock.DockManagerFake
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
@@ -108,6 +109,7 @@
private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
private lateinit var qrCodeScannerAffordanceConfig: FakeKeyguardQuickAffordanceConfig
+ private lateinit var dockManager: DockManagerFake
@Before
fun setUp() {
@@ -123,6 +125,7 @@
)
qrCodeScannerAffordanceConfig =
FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER)
+ dockManager = DockManagerFake()
registry =
FakeKeyguardQuickAffordanceRegistry(
mapOf(
@@ -235,6 +238,7 @@
launchAnimator = launchAnimator,
logger = logger,
devicePolicyManager = devicePolicyManager,
+ dockManager = dockManager,
backgroundDispatcher = testDispatcher,
),
bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),