summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt28
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt61
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt25
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt44
10 files changed, 161 insertions, 33 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
index 4555f13a1a2c..cc64a7dfce10 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
@@ -19,9 +19,10 @@
package com.android.systemui.keyguard.ui.composable
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.indication
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
@@ -33,10 +34,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.input.pointer.pointerInput
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture
import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
/** Container for lockscreen content that handles long-press to bring up the settings menu. */
@Composable
+// TODO(b/344879669): now that it's more generic than long-press, rename it.
fun LockscreenLongPress(
viewModel: KeyguardLongPressViewModel,
modifier: Modifier = Modifier,
@@ -50,14 +53,17 @@ fun LockscreenLongPress(
Box(
modifier =
modifier
- .combinedClickable(
- enabled = isEnabled,
- onLongClick = viewModel::onLongPress,
- onClick = {},
- interactionSource = interactionSource,
- // Passing null for the indication removes the ripple effect.
- indication = null,
- )
+ .pointerInput(isEnabled) {
+ if (isEnabled) {
+ detectLongPressGesture { viewModel.onLongPress() }
+ }
+ }
+ .pointerInput(Unit) {
+ detectTapGestures(
+ onTap = { viewModel.onClick(it.x, it.y) },
+ onDoubleTap = { viewModel.onDoubleClick() },
+ )
+ }
.pointerInput(settingsMenuBounds) {
awaitEachGesture {
val pointerInputChange = awaitFirstDown()
@@ -65,7 +71,9 @@ fun LockscreenLongPress(
viewModel.onTouchedOutside()
}
}
- },
+ }
+ // Passing null for the indication removes the ripple effect.
+ .indication(interactionSource, null)
) {
content(setSettingsMenuBounds)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
index 9d34903d544d..da3de3220267 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
@@ -32,6 +32,7 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepos
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
+import com.android.systemui.shade.pulsingGestureListener
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
@@ -300,7 +301,8 @@ class KeyguardLongPressInteractorTest : SysuiTestCase() {
set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, isOpenWppDirectlyEnabled)
},
broadcastDispatcher = fakeBroadcastDispatcher,
- accessibilityManager = kosmos.accessibilityManagerWrapper
+ accessibilityManager = kosmos.accessibilityManagerWrapper,
+ pulsingGestureListener = kosmos.pulsingGestureListener,
)
setUpState()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
index bb6215a8b215..5f646a7ce547 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
@@ -32,6 +32,7 @@ import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.res.R
+import com.android.systemui.shade.PulsingGestureListener
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -54,6 +55,7 @@ import kotlinx.coroutines.launch
/** Business logic for use-cases related to the keyguard long-press feature. */
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
+// TODO(b/344879669): now that it's more generic than long-press, rename it.
class KeyguardLongPressInteractor
@Inject
constructor(
@@ -65,6 +67,7 @@ constructor(
private val featureFlags: FeatureFlags,
broadcastDispatcher: BroadcastDispatcher,
private val accessibilityManager: AccessibilityManagerWrapper,
+ private val pulsingGestureListener: PulsingGestureListener,
) {
/** Whether the long-press handling feature should be enabled. */
val isLongPressHandlingEnabled: StateFlow<Boolean> =
@@ -166,6 +169,16 @@ constructor(
_shouldOpenSettings.value = false
}
+ /** Notifies that the lockscreen has been clicked at position [x], [y]. */
+ fun onClick(x: Float, y: Float) {
+ pulsingGestureListener.onSingleTapUp(x, y)
+ }
+
+ /** Notifies that the lockscreen has been double clicked. */
+ fun onDoubleClick() {
+ pulsingGestureListener.onDoubleTapEvent()
+ }
+
private fun showSettings() {
_shouldOpenSettings.value = true
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
index c73931a12455..90fef6fb64e0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
@@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.Flow
/** Models UI state to support the lock screen long-press feature. */
@SysUISingleton
+// TODO(b/344879669): now that it's more generic than long-press, rename it.
class KeyguardLongPressViewModel
@Inject
constructor(
@@ -45,4 +46,14 @@ constructor(
fun onTouchedOutside() {
interactor.onTouchedOutside()
}
+
+ /** Notifies that the lockscreen has been clicked at position [x], [y]. */
+ fun onClick(x: Float, y: Float) {
+ interactor.onClick(x, y)
+ }
+
+ /** Notifies that the lockscreen has been double clicked. */
+ fun onDoubleClick() {
+ interactor.onDoubleClick()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index e41f99b99e35..9cddf86a40e6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -369,7 +369,9 @@ public class NotificationShadeWindowViewController implements Dumpable {
}
mFalsingCollector.onTouchEvent(ev);
- mPulsingWakeupGestureHandler.onTouchEvent(ev);
+ if (!SceneContainerFlag.isEnabled()) {
+ mPulsingWakeupGestureHandler.onTouchEvent(ev);
+ }
if (!SceneContainerFlag.isEnabled()
&& mGlanceableHubContainerController.onTouchEvent(ev)) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
index fe4832f0895b..062327dc2acf 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
@@ -47,17 +47,19 @@ import javax.inject.Inject
* display state, wake-ups are handled by [com.android.systemui.doze.DozeSensors].
*/
@SysUISingleton
-class PulsingGestureListener @Inject constructor(
- private val falsingManager: FalsingManager,
- private val dockManager: DockManager,
- private val powerInteractor: PowerInteractor,
- private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
- private val statusBarStateController: StatusBarStateController,
- private val shadeLogger: ShadeLogger,
- private val dozeInteractor: DozeInteractor,
- userTracker: UserTracker,
- tunerService: TunerService,
- dumpManager: DumpManager
+class PulsingGestureListener
+@Inject
+constructor(
+ private val falsingManager: FalsingManager,
+ private val dockManager: DockManager,
+ private val powerInteractor: PowerInteractor,
+ private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
+ private val statusBarStateController: StatusBarStateController,
+ private val shadeLogger: ShadeLogger,
+ private val dozeInteractor: DozeInteractor,
+ userTracker: UserTracker,
+ tunerService: TunerService,
+ dumpManager: DumpManager
) : GestureDetector.SimpleOnGestureListener(), Dumpable {
private var doubleTapEnabled = false
private var singleTapEnabled = false
@@ -66,21 +68,27 @@ class PulsingGestureListener @Inject constructor(
val tunable = Tunable { key: String?, _: String? ->
when (key) {
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
- doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
- userTracker.userId)
+ doubleTapEnabled =
+ ambientDisplayConfiguration.doubleTapGestureEnabled(userTracker.userId)
Settings.Secure.DOZE_TAP_SCREEN_GESTURE ->
- singleTapEnabled = ambientDisplayConfiguration.tapGestureEnabled(
- userTracker.userId)
+ singleTapEnabled =
+ ambientDisplayConfiguration.tapGestureEnabled(userTracker.userId)
}
}
- tunerService.addTunable(tunable,
- Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
- Settings.Secure.DOZE_TAP_SCREEN_GESTURE)
+ tunerService.addTunable(
+ tunable,
+ Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
+ Settings.Secure.DOZE_TAP_SCREEN_GESTURE
+ )
dumpManager.registerDumpable(this)
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
+ return onSingleTapUp(e.x, e.y)
+ }
+
+ fun onSingleTapUp(x: Float, y: Float): Boolean {
val isNotDocked = !dockManager.isDocked
shadeLogger.logSingleTapUp(statusBarStateController.isDozing, singleTapEnabled, isNotDocked)
if (statusBarStateController.isDozing && singleTapEnabled && isNotDocked) {
@@ -89,11 +97,13 @@ class PulsingGestureListener @Inject constructor(
shadeLogger.logSingleTapUpFalsingState(proximityIsNotNear, isNotAFalseTap)
if (proximityIsNotNear && isNotAFalseTap) {
shadeLogger.d("Single tap handled, requesting centralSurfaces.wakeUpIfDozing")
- dozeInteractor.setLastTapToWakePosition(Point(e.x.toInt(), e.y.toInt()))
+ dozeInteractor.setLastTapToWakePosition(Point(x.toInt(), y.toInt()))
powerInteractor.wakeUpIfDozing("PULSING_SINGLE_TAP", PowerManager.WAKE_REASON_TAP)
}
+
return true
}
+
shadeLogger.d("onSingleTapUp event ignored")
return false
}
@@ -103,10 +113,18 @@ class PulsingGestureListener @Inject constructor(
* motion events for a double tap.
*/
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
+ if (e.actionMasked != MotionEvent.ACTION_UP) {
+ return false
+ }
+
+ return onDoubleTapEvent()
+ }
+
+ fun onDoubleTapEvent(): Boolean {
// React to the [MotionEvent.ACTION_UP] event after double tap is detected. Falsing
// checks MUST be on the ACTION_UP event.
- if (e.actionMasked == MotionEvent.ACTION_UP &&
- statusBarStateController.isDozing &&
+ if (
+ statusBarStateController.isDozing &&
(doubleTapEnabled || singleTapEnabled) &&
!falsingManager.isProximityNear &&
!falsingManager.isFalseDoubleTap
@@ -114,6 +132,7 @@ class PulsingGestureListener @Inject constructor(
powerInteractor.wakeUpIfDozing("PULSING_DOUBLE_TAP", PowerManager.WAKE_REASON_TAP)
return true
}
+
return false
}
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 bdc5fc34158f..68a6e777e97d 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
@@ -58,6 +58,7 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.pulsingGestureListener
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -221,6 +222,7 @@ class KeyguardBottomAreaViewModelTest(flags: FlagsParameterization) : SysuiTestC
featureFlags = featureFlags,
broadcastDispatcher = broadcastDispatcher,
accessibilityManager = accessibilityManager,
+ pulsingGestureListener = kosmos.pulsingGestureListener,
)
underTest =
KeyguardBottomAreaViewModel(
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt b/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt
new file mode 100644
index 000000000000..3f3c30f0faec
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt
@@ -0,0 +1,25 @@
+/*
+ * 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 android.hardware.display
+
+import android.content.applicationContext
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.ambientDisplayConfiguration by Fixture {
+ FakeAmbientDisplayConfiguration(applicationContext)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
index c06f833c9e96..cd0d554e6b1d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
@@ -24,6 +24,7 @@ import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.shade.pulsingGestureListener
val Kosmos.keyguardLongPressInteractor by
Kosmos.Fixture {
@@ -36,5 +37,6 @@ val Kosmos.keyguardLongPressInteractor by
featureFlags = featureFlagsClassic,
broadcastDispatcher = broadcastDispatcher,
accessibilityManager = accessibilityManagerWrapper,
+ pulsingGestureListener = pulsingGestureListener,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt
new file mode 100644
index 000000000000..4fc22289585f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.shade
+
+import android.hardware.display.ambientDisplayConfiguration
+import com.android.systemui.classifier.falsingManager
+import com.android.systemui.dock.dockManager
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.keyguard.domain.interactor.dozeInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.settings.userTracker
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.pulsingGestureListener by Fixture {
+ PulsingGestureListener(
+ falsingManager = falsingManager,
+ dockManager = dockManager,
+ powerInteractor = powerInteractor,
+ ambientDisplayConfiguration = ambientDisplayConfiguration,
+ statusBarStateController = statusBarStateController,
+ shadeLogger = mock(),
+ dozeInteractor = dozeInteractor,
+ userTracker = userTracker,
+ tunerService = mock(),
+ dumpManager = dumpManager,
+ )
+}