Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationsInteractorTest.kt +21 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi import com.android.systemui.statusbar.notification.promoted.fake import com.android.systemui.statusbar.notification.promoted.showPromotedNotificationsOnAOD import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization import com.android.systemui.statusbar.policy.domain.interactor.sensitiveNotificationProtectionInteractor import com.android.systemui.statusbar.policy.mockSensitiveNotificationProtectionController Loading @@ -62,11 +64,14 @@ class AODPromotedNotificationsInteractorTest : SysuiTestCase() { sensitiveNotificationProtectionInteractor = sensitiveNotificationProtectionInteractor, dumpManager = dumpManager, biometricUnlockInteractor = biometricUnlockInteractor, showPromotedNotificationsOnAOD = showPromotedNotificationsOnAOD, ) } @Before fun setUp() { // by default, showing RON on AOD is enabled kosmos.showPromotedNotificationsOnAOD.fake.isEnabled = true kosmos.statusBarNotificationChipsInteractor.start() } Loading @@ -81,6 +86,22 @@ class AODPromotedNotificationsInteractorTest : SysuiTestCase() { ) } @Test fun content_null_when_showing_ron_on_aod_disabled() = kosmos.runTest { // GIVEN a promoted entry val ronEntry = buildPublicPrivatePromotedOngoing() setKeyguardLocked(false) setScreenSharingProtectionActive(false) showPromotedNotificationsOnAOD.fake.isEnabled = false renderNotificationListInteractor.setRenderedList(listOf(ronEntry)) // THEN aod content is null val content by collectLastValue(underTest.content) assertThat(content).isNull() } @Test fun content_sensitive_unlocked() = kosmos.runTest { Loading packages/SystemUI/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1129,6 +1129,9 @@ <!-- Whether or not to show the UMO on the glanceable hub when media is playing. --> <bool name="config_showUmoOnHub">false</bool> <!-- Whether or not to show the promoted notifications on AOD. --> <bool name="config_showPromotedNotificationsOnAOD">true</bool> <!-- Whether to enable the desktop specific audio tile details view. --> <bool name="config_enableDesktopAudioTileDetailsView">false</bool> Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +9 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ import com.android.systemui.statusbar.notification.logging.NotificationPanelLogg import com.android.systemui.statusbar.notification.logging.dagger.NotificationsLogModule; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractorImpl; import com.android.systemui.statusbar.notification.promoted.ShowPromotedNotificationsOnAOD; import com.android.systemui.statusbar.notification.promoted.ShowPromotedNotificationsOnAODImpl; import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel; import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactory; import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactoryLooperImpl; Loading Loading @@ -331,6 +333,13 @@ public interface NotificationsModule { } } /** * Provides the default implementation of {@link ShowPromotedNotificationsOnAOD} */ @Binds @SysUISingleton ShowPromotedNotificationsOnAOD provideShowPromotedNotificationsOnAOD( ShowPromotedNotificationsOnAODImpl impl); /** * Provide an implementation of {@link MagneticNotificationRowManager} based on its flag. */ Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ShowPromotedNotificationOnAOD.kt 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.statusbar.notification.promoted import android.content.Context import com.android.systemui.dagger.SysUISingleton import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject interface ShowPromotedNotificationsOnAOD { val isEnabled: Boolean } @SysUISingleton class ShowPromotedNotificationsOnAODImpl @Inject constructor(@ShadeDisplayAware private val context: Context) : ShowPromotedNotificationsOnAOD { override val isEnabled: Boolean = context.resources.getBoolean(R.bool.config_showPromotedNotificationsOnAOD) } packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt +25 −8 Original line number Diff line number Diff line Loading @@ -21,13 +21,18 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.BiometricUnlockInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.statusbar.notification.promoted.ShowPromotedNotificationsOnAOD import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.policy.domain.interactor.SensitiveNotificationProtectionInteractor import com.android.systemui.util.asIndenting import com.android.systemui.util.kotlin.FlowDumperImpl import com.android.systemui.util.println import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @SysUISingleton Loading @@ -37,10 +42,13 @@ constructor( promotedNotificationsInteractor: PromotedNotificationsInteractor, keyguardInteractor: KeyguardInteractor, sensitiveNotificationProtectionInteractor: SensitiveNotificationProtectionInteractor, showPromotedNotificationsOnAOD: ShowPromotedNotificationsOnAOD, dumpManager: DumpManager, biometricUnlockInteractor: BiometricUnlockInteractor, ) : FlowDumperImpl(dumpManager) { private val promotedNotifsAODEnabled = showPromotedNotificationsOnAOD.isEnabled /** * Whether the system is unlocked, not screensharing such that private notification content is * allowed to show on the aod, and a biometric is not about to dismiss the keyguard Loading @@ -58,6 +66,9 @@ constructor( /** The content to show as the promoted notification on AOD */ val content: Flow<PromotedNotificationContentModel?> = if (!promotedNotifsAODEnabled) { flowOf(null) } else { combine( promotedNotificationsInteractor.aodPromotedNotification, canShowPrivateNotificationContent, Loading @@ -66,6 +77,12 @@ constructor( else promotedContent?.publicVersion } .distinctUntilNewInstance() } override fun dump(pw: PrintWriter, args: Array<out String>) { super.dump(pw, args) pw.asIndenting().println("showPromotedNotificationsOnAOD", promotedNotifsAODEnabled) } val isPresent: Flow<Boolean> = content.map { it != null }.dumpWhileCollecting("isPresent") Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationsInteractorTest.kt +21 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi import com.android.systemui.statusbar.notification.promoted.fake import com.android.systemui.statusbar.notification.promoted.showPromotedNotificationsOnAOD import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization import com.android.systemui.statusbar.policy.domain.interactor.sensitiveNotificationProtectionInteractor import com.android.systemui.statusbar.policy.mockSensitiveNotificationProtectionController Loading @@ -62,11 +64,14 @@ class AODPromotedNotificationsInteractorTest : SysuiTestCase() { sensitiveNotificationProtectionInteractor = sensitiveNotificationProtectionInteractor, dumpManager = dumpManager, biometricUnlockInteractor = biometricUnlockInteractor, showPromotedNotificationsOnAOD = showPromotedNotificationsOnAOD, ) } @Before fun setUp() { // by default, showing RON on AOD is enabled kosmos.showPromotedNotificationsOnAOD.fake.isEnabled = true kosmos.statusBarNotificationChipsInteractor.start() } Loading @@ -81,6 +86,22 @@ class AODPromotedNotificationsInteractorTest : SysuiTestCase() { ) } @Test fun content_null_when_showing_ron_on_aod_disabled() = kosmos.runTest { // GIVEN a promoted entry val ronEntry = buildPublicPrivatePromotedOngoing() setKeyguardLocked(false) setScreenSharingProtectionActive(false) showPromotedNotificationsOnAOD.fake.isEnabled = false renderNotificationListInteractor.setRenderedList(listOf(ronEntry)) // THEN aod content is null val content by collectLastValue(underTest.content) assertThat(content).isNull() } @Test fun content_sensitive_unlocked() = kosmos.runTest { Loading
packages/SystemUI/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1129,6 +1129,9 @@ <!-- Whether or not to show the UMO on the glanceable hub when media is playing. --> <bool name="config_showUmoOnHub">false</bool> <!-- Whether or not to show the promoted notifications on AOD. --> <bool name="config_showPromotedNotificationsOnAOD">true</bool> <!-- Whether to enable the desktop specific audio tile details view. --> <bool name="config_enableDesktopAudioTileDetailsView">false</bool> Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +9 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ import com.android.systemui.statusbar.notification.logging.NotificationPanelLogg import com.android.systemui.statusbar.notification.logging.dagger.NotificationsLogModule; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractorImpl; import com.android.systemui.statusbar.notification.promoted.ShowPromotedNotificationsOnAOD; import com.android.systemui.statusbar.notification.promoted.ShowPromotedNotificationsOnAODImpl; import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel; import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactory; import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactoryLooperImpl; Loading Loading @@ -331,6 +333,13 @@ public interface NotificationsModule { } } /** * Provides the default implementation of {@link ShowPromotedNotificationsOnAOD} */ @Binds @SysUISingleton ShowPromotedNotificationsOnAOD provideShowPromotedNotificationsOnAOD( ShowPromotedNotificationsOnAODImpl impl); /** * Provide an implementation of {@link MagneticNotificationRowManager} based on its flag. */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ShowPromotedNotificationOnAOD.kt 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.statusbar.notification.promoted import android.content.Context import com.android.systemui.dagger.SysUISingleton import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject interface ShowPromotedNotificationsOnAOD { val isEnabled: Boolean } @SysUISingleton class ShowPromotedNotificationsOnAODImpl @Inject constructor(@ShadeDisplayAware private val context: Context) : ShowPromotedNotificationsOnAOD { override val isEnabled: Boolean = context.resources.getBoolean(R.bool.config_showPromotedNotificationsOnAOD) }
packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/AODPromotedNotificationInteractor.kt +25 −8 Original line number Diff line number Diff line Loading @@ -21,13 +21,18 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.BiometricUnlockInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.statusbar.notification.promoted.ShowPromotedNotificationsOnAOD import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.policy.domain.interactor.SensitiveNotificationProtectionInteractor import com.android.systemui.util.asIndenting import com.android.systemui.util.kotlin.FlowDumperImpl import com.android.systemui.util.println import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @SysUISingleton Loading @@ -37,10 +42,13 @@ constructor( promotedNotificationsInteractor: PromotedNotificationsInteractor, keyguardInteractor: KeyguardInteractor, sensitiveNotificationProtectionInteractor: SensitiveNotificationProtectionInteractor, showPromotedNotificationsOnAOD: ShowPromotedNotificationsOnAOD, dumpManager: DumpManager, biometricUnlockInteractor: BiometricUnlockInteractor, ) : FlowDumperImpl(dumpManager) { private val promotedNotifsAODEnabled = showPromotedNotificationsOnAOD.isEnabled /** * Whether the system is unlocked, not screensharing such that private notification content is * allowed to show on the aod, and a biometric is not about to dismiss the keyguard Loading @@ -58,6 +66,9 @@ constructor( /** The content to show as the promoted notification on AOD */ val content: Flow<PromotedNotificationContentModel?> = if (!promotedNotifsAODEnabled) { flowOf(null) } else { combine( promotedNotificationsInteractor.aodPromotedNotification, canShowPrivateNotificationContent, Loading @@ -66,6 +77,12 @@ constructor( else promotedContent?.publicVersion } .distinctUntilNewInstance() } override fun dump(pw: PrintWriter, args: Array<out String>) { super.dump(pw, args) pw.asIndenting().println("showPromotedNotificationsOnAOD", promotedNotifsAODEnabled) } val isPresent: Flow<Boolean> = content.map { it != null }.dumpWhileCollecting("isPresent") Loading