summaryrefslogtreecommitdiff
path: root/packages/SystemUI
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt62
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt33
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldRemoteFilter.kt2
3 files changed, 85 insertions, 12 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 82bd45ce2279..6322edf5a1b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -24,6 +24,10 @@ import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.expansionChanges
@@ -40,22 +44,26 @@ import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.headsUpEvents
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
-import javax.inject.Inject
-import kotlin.time.Duration
-import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.launch
+import kotlinx.coroutines.yield
+import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
/**
* Filters low priority and privacy-sensitive notifications from the lockscreen, and hides section
@@ -69,6 +77,7 @@ constructor(
private val headsUpManager: HeadsUpManager,
private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
private val keyguardRepository: KeyguardRepository,
+ private val keyguardTransitionRepository: KeyguardTransitionRepository,
private val notifPipelineFlags: NotifPipelineFlags,
@Application private val scope: CoroutineScope,
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
@@ -99,21 +108,46 @@ constructor(
}
private suspend fun trackUnseenNotificationsWhileUnlocked() {
+ // Whether or not we're actively tracking unseen notifications to mark them as seen when
+ // appropriate.
+ val isTrackingUnseen: Flow<Boolean> =
+ keyguardRepository.isKeyguardShowing
+ // transformLatest so that we can cancel listening to keyguard transitions once
+ // isKeyguardShowing changes (after a successful transition to the keyguard).
+ .transformLatest { isShowing ->
+ if (isShowing) {
+ // If the keyguard is showing, we're not tracking unseen.
+ emit(false)
+ } else {
+ // If the keyguard stops showing, then start tracking unseen notifications.
+ emit(true)
+ // If the screen is turning off, stop tracking, but if that transition is
+ // cancelled, then start again.
+ emitAll(
+ keyguardTransitionRepository.transitions
+ .map { step -> !step.isScreenTurningOff }
+ )
+ }
+ }
+ // Prevent double emit of `false` caused by transition to AOD, followed by keyguard
+ // showing
+ .distinctUntilChanged()
+
// Use collectLatest so that trackUnseenNotifications() is cancelled when the keyguard is
// showing again
- var clearUnseenOnUnlock = false
- keyguardRepository.isKeyguardShowing.collectLatest { isKeyguardShowing ->
- if (isKeyguardShowing) {
+ var clearUnseenOnBeginTracking = false
+ isTrackingUnseen.collectLatest { trackingUnseen ->
+ if (!trackingUnseen) {
// Wait for the user to spend enough time on the lock screen before clearing unseen
// set when unlocked
awaitTimeSpentNotDozing(SEEN_TIMEOUT)
- clearUnseenOnUnlock = true
+ clearUnseenOnBeginTracking = true
} else {
- unseenNotifFilter.invalidateList("keyguard no longer showing")
- if (clearUnseenOnUnlock) {
- clearUnseenOnUnlock = false
+ if (clearUnseenOnBeginTracking) {
+ clearUnseenOnBeginTracking = false
unseenNotifications.clear()
}
+ unseenNotifFilter.invalidateList("keyguard no longer showing")
trackUnseenNotifications()
}
}
@@ -142,7 +176,10 @@ constructor(
}
private suspend fun clearUnseenNotificationsWhenShadeIsExpanded() {
- statusBarStateController.expansionChanges.collect { isExpanded ->
+ statusBarStateController.expansionChanges.collectLatest { isExpanded ->
+ // Give keyguard events time to propagate, in case this expansion is part of the
+ // keyguard transition and not the user expanding the shade
+ yield()
if (isExpanded) {
unseenNotifications.clear()
}
@@ -276,3 +313,6 @@ constructor(
private val SEEN_TIMEOUT = 5.seconds
}
}
+
+private val TransitionStep.isScreenTurningOff: Boolean get() =
+ transitionState == TransitionState.STARTED && to != KeyguardState.GONE \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 8109e24a1e52..c2a2a40b7e5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -25,6 +25,10 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.advanceTimeBy
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.NotifPipelineFlags
@@ -69,6 +73,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
private val headsUpManager: HeadsUpManager = mock()
private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
private val keyguardRepository = FakeKeyguardRepository()
+ private val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
private val notifPipelineFlags: NotifPipelineFlags = mock()
private val notifPipeline: NotifPipeline = mock()
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
@@ -118,6 +123,33 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
}
@Test
+ fun unseenFilterStopsMarkingSeenNotifWhenTransitionToAod() {
+ whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
+
+ // GIVEN: Keyguard is not showing, shade is not expanded, and a notification is present
+ keyguardRepository.setKeyguardShowing(false)
+ whenever(statusBarStateController.isExpanded).thenReturn(false)
+ runKeyguardCoordinatorTest {
+ val fakeEntry = NotificationEntryBuilder().build()
+ collectionListener.onEntryAdded(fakeEntry)
+
+ // WHEN: The device transitions to AOD
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(to = KeyguardState.AOD, transitionState = TransitionState.STARTED),
+ )
+ testScheduler.runCurrent()
+
+ // WHEN: The shade is expanded
+ whenever(statusBarStateController.isExpanded).thenReturn(true)
+ statusBarStateListener.onExpandedChanged(true)
+ testScheduler.runCurrent()
+
+ // THEN: The notification is still treated as "unseen" and is not filtered out.
+ assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
+ }
+ }
+
+ @Test
fun unseenFilter_headsUpMarkedAsSeen() {
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
@@ -373,6 +405,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
headsUpManager,
keyguardNotifVisibilityProvider,
keyguardRepository,
+ keyguardTransitionRepository,
notifPipelineFlags,
testScope.backgroundScope,
sectionHeaderVisibilityProvider,
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldRemoteFilter.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldRemoteFilter.kt
index 0b019d1285e3..30418883eaf8 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldRemoteFilter.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldRemoteFilter.kt
@@ -35,7 +35,7 @@ class UnfoldRemoteFilter(
private var inProgress = false
- private var processedProgress: Float = 0.0f
+ private var processedProgress: Float = 1.0f
set(newProgress) {
if (inProgress) {
logCounter({ "$TAG#filtered_progress" }, newProgress)