Broadcast any demotion action
Fixes: 391661009
Test: atest SystemUITests
Flag: com.android.systemui.promote_notifications_automatically
Change-Id: I0d45ce73186453723dc079ca06e3fbc822749388
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
index 1b8d64d..4a954b3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
@@ -71,6 +71,7 @@
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
import com.android.systemui.statusbar.notification.row.icon.appIconProvider
@@ -80,6 +81,9 @@
import com.android.systemui.testKosmos
import com.android.systemui.util.kotlin.JavaAdapter
import com.android.systemui.wmshell.BubblesManager
+import java.util.Optional
+import kotlin.test.assertNotNull
+import kotlin.test.fail
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
@@ -107,9 +111,6 @@
import org.mockito.kotlin.whenever
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
-import java.util.Optional
-import kotlin.test.assertNotNull
-import kotlin.test.fail
/** Tests for [NotificationGutsManager]. */
@SmallTest
@@ -149,6 +150,7 @@
@Mock private lateinit var launcherApps: LauncherApps
@Mock private lateinit var shortcutManager: ShortcutManager
@Mock private lateinit var channelEditorDialogController: ChannelEditorDialogController
+ @Mock private lateinit var packageDemotionInteractor: PackageDemotionInteractor
@Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
@Mock private lateinit var contextTracker: UserContextProvider
@Mock private lateinit var bubblesManager: BubblesManager
@@ -214,6 +216,7 @@
launcherApps,
shortcutManager,
channelEditorDialogController,
+ packageDemotionInteractor,
contextTracker,
assistantFeedbackController,
Optional.of(bubblesManager),
@@ -521,6 +524,7 @@
any<NotificationIconStyleProvider>(),
eq(onUserInteractionCallback),
eq(channelEditorDialogController),
+ any<PackageDemotionInteractor>(),
eq(statusBarNotification.packageName),
any<NotificationChannel>(),
eq(entry),
@@ -560,6 +564,7 @@
any<NotificationIconStyleProvider>(),
eq(onUserInteractionCallback),
eq(channelEditorDialogController),
+ any<PackageDemotionInteractor>(),
eq(statusBarNotification.packageName),
any<NotificationChannel>(),
eq(entry),
@@ -597,6 +602,7 @@
any<NotificationIconStyleProvider>(),
eq(onUserInteractionCallback),
eq(channelEditorDialogController),
+ any<PackageDemotionInteractor>(),
eq(statusBarNotification.packageName),
any<NotificationChannel>(),
eq(entry),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
index 96ae070..5f817de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
@@ -64,6 +64,7 @@
import com.android.systemui.statusbar.notification.AssistantFeedbackController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
import com.android.systemui.statusbar.notification.row.icon.appIconProvider
@@ -105,6 +106,7 @@
private val onUserInteractionCallback = mock<OnUserInteractionCallback>()
private val mockINotificationManager = mock<INotificationManager>()
private val channelEditorDialogController = mock<ChannelEditorDialogController>()
+ private val packageDemotionInteractor = mock<PackageDemotionInteractor>()
private val assistantFeedbackController = mock<AssistantFeedbackController>()
@Before
@@ -871,6 +873,7 @@
onUserInteractionCallback: OnUserInteractionCallback = this.onUserInteractionCallback,
channelEditorDialogController: ChannelEditorDialogController =
this.channelEditorDialogController,
+ packageDemotionInteractor: PackageDemotionInteractor = this.packageDemotionInteractor,
pkg: String = TEST_PACKAGE_NAME,
notificationChannel: NotificationChannel = this.notificationChannel,
entry: NotificationEntry = this.entry,
@@ -892,6 +895,7 @@
iconStyleProvider,
onUserInteractionCallback,
channelEditorDialogController,
+ packageDemotionInteractor,
pkg,
notificationChannel,
entry,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
index 5638e0b..3887297 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
@@ -48,6 +48,7 @@
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor;
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider;
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
@@ -92,6 +93,8 @@
@Mock
private ChannelEditorDialogController mChannelEditorDialogController;
@Mock
+ private PackageDemotionInteractor mPackageDemotionInteractor;
+ @Mock
private AssistantFeedbackController mAssistantFeedbackController;
@Mock
private TelecomManager mTelecomManager;
@@ -138,6 +141,7 @@
mMockIconStyleProvider,
mOnUserInteractionCallback,
mChannelEditorDialogController,
+ mPackageDemotionInteractor,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PackageDemotionInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PackageDemotionInteractor.kt
new file mode 100644
index 0000000..1429535
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PackageDemotionInteractor.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** A class which can receive both a demotion signal and a single handler of that signal */
+@SysUISingleton
+class PackageDemotionInteractor @Inject constructor() {
+ private var demotionSignalHandler: ((packageName: String, uid: Int) -> Unit)? = null
+
+ /**
+ * called after sending a the demotion signal to
+ * [android.app.INotificationManager.setCanBePromoted]
+ */
+ fun onPackageDemoted(packageName: String, uid: Int) {
+ demotionSignalHandler?.invoke(packageName, uid)
+ }
+
+ /** sets the [handler] that will be called when [onPackageDemoted] is called. */
+ fun setOnPackageDemotionHandler(handler: (packageName: String, uid: Int) -> Unit) {
+ demotionSignalHandler = handler
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 9a75253..55a5649 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -71,6 +71,7 @@
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener;
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor;
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider;
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
@@ -100,6 +101,7 @@
private final AccessibilityManager mAccessibilityManager;
private final HighPriorityProvider mHighPriorityProvider;
private final ChannelEditorDialogController mChannelEditorDialogController;
+ private final PackageDemotionInteractor mPackageDemotionInteractor;
private final OnUserInteractionCallback mOnUserInteractionCallback;
// Dependencies:
@@ -155,6 +157,7 @@
LauncherApps launcherApps,
ShortcutManager shortcutManager,
ChannelEditorDialogController channelEditorDialogController,
+ PackageDemotionInteractor packageDemotionInteractor,
UserContextProvider contextTracker,
AssistantFeedbackController assistantFeedbackController,
Optional<BubblesManager> bubblesManagerOptional,
@@ -184,6 +187,7 @@
mShortcutManager = shortcutManager;
mContextTracker = contextTracker;
mChannelEditorDialogController = channelEditorDialogController;
+ mPackageDemotionInteractor = packageDemotionInteractor;
mAssistantFeedbackController = assistantFeedbackController;
mBubblesManagerOptional = bubblesManagerOptional;
mUiEventLogger = uiEventLogger;
@@ -429,6 +433,7 @@
mIconStyleProvider,
mOnUserInteractionCallback,
mChannelEditorDialogController,
+ mPackageDemotionInteractor,
packageName,
row.getEntry().getChannel(),
row.getEntry(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 6611225..904911f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -74,6 +74,7 @@
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor;
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider;
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
@@ -193,6 +194,7 @@
NotificationIconStyleProvider iconStyleProvider,
OnUserInteractionCallback onUserInteractionCallback,
ChannelEditorDialogController channelEditorDialogController,
+ PackageDemotionInteractor packageDemotionInteractor,
String pkg,
NotificationChannel notificationChannel,
NotificationEntry entry,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
index 6ff711d..39ffdf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
@@ -31,6 +31,7 @@
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor;
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider;
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
@@ -42,6 +43,7 @@
public class PromotedNotificationInfo extends NotificationInfo {
private static final String TAG = "PromotedNotifInfoGuts";
private INotificationManager mNotificationManager;
+ private PackageDemotionInteractor mPackageDemotionInteractor;
private NotificationGuts mGutsContainer;
public PromotedNotificationInfo(Context context, AttributeSet attrs) {
@@ -56,6 +58,7 @@
NotificationIconStyleProvider iconStyleProvider,
OnUserInteractionCallback onUserInteractionCallback,
ChannelEditorDialogController channelEditorDialogController,
+ PackageDemotionInteractor packageDemotionInteractor,
String pkg,
NotificationChannel notificationChannel,
NotificationEntry entry,
@@ -69,12 +72,14 @@
AssistantFeedbackController assistantFeedbackController,
MetricsLogger metricsLogger, OnClickListener onCloseClick) throws RemoteException {
super.bindNotification(pm, iNotificationManager, appIconProvider, iconStyleProvider,
- onUserInteractionCallback, channelEditorDialogController, pkg, notificationChannel,
+ onUserInteractionCallback, channelEditorDialogController, packageDemotionInteractor,
+ pkg, notificationChannel,
entry, onSettingsClick, onAppSettingsClick, feedbackClickListener, uiEventLogger,
isDeviceProvisioned, isNonblockable, wasShownHighPriority,
assistantFeedbackController, metricsLogger, onCloseClick);
mNotificationManager = iNotificationManager;
+ mPackageDemotionInteractor = packageDemotionInteractor;
bindDemote(entry.getSbn(), pkg);
}
@@ -94,8 +99,8 @@
private OnClickListener getDemoteClickListener(StatusBarNotification sbn, String packageName) {
return ((View v) -> {
try {
- // TODO(b/391661009): Signal AutomaticPromotionCoordinator here
mNotificationManager.setCanBePromoted(packageName, sbn.getUid(), false, true);
+ mPackageDemotionInteractor.onPackageDemoted(packageName, sbn.getUid());
mGutsContainer.closeControls(v, true);
} catch (RemoteException e) {
Log.e(TAG, "Couldn't revoke live update permission", e);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 0c0ef9d..ee9a5f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -67,6 +67,7 @@
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor
import com.android.systemui.statusbar.notification.row.icon.appIconProvider
import com.android.systemui.statusbar.notification.row.icon.notificationIconStyleProvider
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
@@ -146,6 +147,7 @@
@Mock private lateinit var notificationManager: INotificationManager
@Mock private lateinit var shortcutManager: ShortcutManager
@Mock private lateinit var channelEditorDialogController: ChannelEditorDialogController
+ @Mock private lateinit var packageDemotionInteractor: PackageDemotionInteractor
@Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
@Mock private lateinit var contextTracker: UserContextProvider
@Mock private lateinit var bubblesManager: BubblesManager
@@ -185,6 +187,7 @@
launcherApps,
shortcutManager,
channelEditorDialogController,
+ packageDemotionInteractor,
contextTracker,
assistantFeedbackController,
Optional.of(bubblesManager),
@@ -438,6 +441,7 @@
eq(iconStyleProvider),
eq(onUserInteractionCallback),
eq(channelEditorDialogController),
+ eq(packageDemotionInteractor),
eq(statusBarNotification.packageName),
any<NotificationChannel>(),
eq(entry),
@@ -473,6 +477,7 @@
eq(iconStyleProvider),
eq(onUserInteractionCallback),
eq(channelEditorDialogController),
+ eq(packageDemotionInteractor),
eq(statusBarNotification.packageName),
any<NotificationChannel>(),
eq(entry),
@@ -508,6 +513,7 @@
eq(iconStyleProvider),
eq(onUserInteractionCallback),
eq(channelEditorDialogController),
+ eq(packageDemotionInteractor),
eq(statusBarNotification.packageName),
any<NotificationChannel>(),
eq(entry),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PackageDemotionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PackageDemotionInteractorKosmos.kt
new file mode 100644
index 0000000..38b5994
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PackageDemotionInteractorKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.packageDemotionInteractor by Kosmos.Fixture { PackageDemotionInteractor() }