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

Commit 994349c6 authored by Dan Sandler's avatar Dan Sandler Committed by Daniel Sandler
Browse files

Rediscover your own notifications.

This new API, NotificationManager.getActiveNotifications(),
allows an app to recover the set of notifications it has
posted that are still active (un-cleared, un-canceled,
visible by the user). Along with the Notification object
you'll get the original tag and id you used to post it,
wrapped up in the somewhat awkwardly-named
StatusBarNotification data structure (previously only used
internally by NoMan/SysUI and NotificationListenerServices).

Bug: 17320461
Change-Id: I8cd610956fafed4e31526b663cebdc31231ad930
parent 8d505ff0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5116,6 +5116,7 @@ package android.app {
    method public void cancel(int);
    method public void cancel(java.lang.String, int);
    method public void cancelAll();
    method public android.service.notification.StatusBarNotification[] getActiveNotifications();
    method public android.app.NotificationManager.Policy getNotificationPolicy(android.app.NotificationManager.Policy.Token);
    method public boolean isNotificationPolicyTokenValid(android.app.NotificationManager.Policy.Token);
    method public void notify(int, android.app.Notification);
+1 −0
Original line number Diff line number Diff line
@@ -5207,6 +5207,7 @@ package android.app {
    method public void cancel(int);
    method public void cancel(java.lang.String, int);
    method public void cancelAll();
    method public android.service.notification.StatusBarNotification[] getActiveNotifications();
    method public android.app.NotificationManager.Policy getNotificationPolicy(android.app.NotificationManager.Policy.Token);
    method public boolean isNotificationPolicyTokenValid(android.app.NotificationManager.Policy.Token);
    method public void notify(int, android.app.Notification);
+2 −0
Original line number Diff line number Diff line
@@ -92,4 +92,6 @@ interface INotificationManager

    byte[] getBackupPayload(int user);
    void applyRestore(in byte[] payload, int user);

    ParceledListSlice getAppActiveNotifications(String callingPkg, int userId);
}
+29 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.Notification.Builder;
import android.app.NotificationManager.Policy.Token;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -35,10 +36,12 @@ import android.os.StrictMode;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.service.notification.IConditionListener;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenModeConfig;
import android.util.Log;

import java.util.Objects;
import java.util.List;

/**
 * Class to notify the user of events that happen.  This is how you tell
@@ -642,4 +645,30 @@ public class NotificationManager
        }
    }

    /**
     * Recover a list of active notifications: ones that have been posted by the calling app that
     * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
     *
     * Each notification is embedded in a {@link StatusBarNotification} object, including the
     * original <code>tag</code> and <code>id</code> supplied to
     * {@link #notify(String, int, Notification) notify()}
     * (via {@link StatusBarNotification#getTag() getTag()} and
     * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
     * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
     *
     * @return An array of {@link StatusBarNotification}.
     */
    public StatusBarNotification[] getActiveNotifications() {
        final INotificationManager service = getService();
        final String pkg = mContext.getPackageName();
        try {
            final ParceledListSlice<StatusBarNotification> parceledList
                    = service.getAppActiveNotifications(pkg, UserHandle.myUserId());
            final List<StatusBarNotification> list = parceledList.getList();
            return list.toArray(new StatusBarNotification[list.size()]);
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
        }
        return new StatusBarNotification[0];
    }
}
+38 −0
Original line number Diff line number Diff line
@@ -1281,6 +1281,44 @@ public class NotificationManagerService extends SystemService {
            return tmp;
        }

        /**
         * Public API for getting a list of current notifications for the calling package/uid.
         *
         * @returns A list of all the package's notifications, in natural order.
         */
        @Override
        public ParceledListSlice<StatusBarNotification> getAppActiveNotifications(String pkg,
                int incomingUserId) {
            checkCallerIsSystemOrSameApp(pkg);
            int userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                    Binder.getCallingUid(), incomingUserId, true, false,
                    "getAppActiveNotifications", pkg);

            final int N = mNotificationList.size();
            final ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>(N);

            synchronized (mNotificationList) {
                for (int i = 0; i < N; i++) {
                    final StatusBarNotification sbn = mNotificationList.get(i).sbn;
                    if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId) {
                        // We could pass back a cloneLight() but clients might get confused and
                        // try to send this thing back to notify() again, which would not work
                        // very well.
                        final StatusBarNotification sbnOut = new StatusBarNotification(
                                sbn.getPackageName(),
                                sbn.getOpPkg(),
                                sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
                                0, // hide score from apps
                                sbn.getNotification().clone(),
                                sbn.getUser(), sbn.getPostTime());
                        list.add(sbnOut);
                    }
                }
            }

            return new ParceledListSlice<StatusBarNotification>(list);
        }

        /**
         * System-only API for getting a list of recent (cleared, no longer shown) notifications.
         *