Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb229226 authored by Valentin Iftime's avatar Valentin Iftime Committed by Iavor-Valentin Iftime
Browse files

Add NotificationDelegate API to unbundle notification

 Allow notifications that were bundled (classified) to be unbundled => restored to their original channel.
 If the original app-provided summary exists, the unbundled notification will also be regrouped back to its original group.

Flag: android.service.notification.notification_regroup_on_classification
Test: atest NotificationManagerServiceTest
Test: atest GroupHelperTest

Bug: 382047364
Change-Id: I5c156b92366c4df98fbdf5e438173f2f93498c6e
parent 45486021
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -236,4 +236,7 @@ interface IStatusBarService

    /** Shows rear display educational dialog */
    void showRearDisplayDialog(int currentBaseState);

    /** Unbundle a categorized notification */
    void unbundleNotification(String key);
}
+2 −0
Original line number Diff line number Diff line
@@ -433,6 +433,8 @@ class FakeStatusBarService : IStatusBarService.Stub() {

    override fun showRearDisplayDialog(currentBaseState: Int) {}

    override fun unbundleNotification(key: String) {}

    companion object {
        const val DEFAULT_DISPLAY_ID = Display.DEFAULT_DISPLAY
        const val SECONDARY_DISPLAY_ID = 2
+6 −0
Original line number Diff line number Diff line
@@ -101,4 +101,10 @@ public interface NotificationDelegate {
    void onNotificationFeedbackReceived(String key, Bundle feedback);

    void prepareForPossibleShutdown();

    /**
     *  Called when the notification should be unbundled.
     * @param key the notification key
     */
    void unbundleNotification(String key);
}
+37 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ import static android.service.notification.Flags.FLAG_NOTIFICATION_CONVERSATION_
import static android.service.notification.Flags.callstyleCallbackApi;
import static android.service.notification.Flags.notificationClassification;
import static android.service.notification.Flags.notificationForceGrouping;
import static android.service.notification.Flags.notificationRegroupOnClassification;
import static android.service.notification.Flags.redactSensitiveNotificationsBigTextStyle;
import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -1851,6 +1852,42 @@ public class NotificationManagerService extends SystemService {
            }
        }
        @Override
        public void unbundleNotification(String key) {
            if (!(notificationClassification() && notificationRegroupOnClassification())) {
                return;
            }
            synchronized (mNotificationLock) {
                NotificationRecord r = mNotificationsByKey.get(key);
                if (r == null) {
                    return;
                }
                if (DBG) {
                    Slog.v(TAG, "unbundleNotification: " + r);
                }
                boolean hasOriginalSummary = false;
                if (r.getSbn().isAppGroup() && r.getNotification().isGroupChild()) {
                    final String oldGroupKey = GroupHelper.getFullAggregateGroupKey(
                            r.getSbn().getPackageName(), r.getOriginalGroupKey(), r.getUserId());
                    NotificationRecord groupSummary = mSummaryByGroupKey.get(oldGroupKey);
                    // We only care about app-provided valid groups
                    hasOriginalSummary = (groupSummary != null
                            && !GroupHelper.isAggregatedGroup(groupSummary));
                }
                // Only NotificationRecord's mChannel is updated when bundled, the Notification
                // mChannelId will always be the original channel.
                String origChannelId = r.getNotification().getChannelId();
                NotificationChannel originalChannel = mPreferencesHelper.getNotificationChannel(
                        r.getSbn().getPackageName(), r.getUid(), origChannelId, false);
                if (originalChannel != null && !origChannelId.equals(r.getChannel().getId())) {
                    r.updateNotificationChannel(originalChannel);
                    mGroupHelper.onNotificationUnbundled(r, hasOriginalSummary);
                }
            }
        }
    };
    NotificationManagerPrivate mNotificationManagerPrivate = new NotificationManagerPrivate() {
+13 −0
Original line number Diff line number Diff line
@@ -2175,6 +2175,19 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
        }
    }

    /**
     *  Called when the notification should be unbundled.
     * @param key the notification key
     */
    @Override
    public void unbundleNotification(@Nullable String key) {
        enforceStatusBarService();
        enforceValidCallingUser();
        Binder.withCleanCallingIdentity(() -> {
            mNotificationDelegate.unbundleNotification(key);
        });
    }


    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
Loading