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

Commit cee44ba4 authored by Christoph Studer's avatar Christoph Studer
Browse files

Simplify NotificationListenerService API

Use ParceledListSlice to send the list of active notifications
from NoMan to NotificationListeners.

This allows us to simplify the API to what it was before
introducing the "String[] key" workaround for dealing with large
numbers of StatusBarNotifications.

While we're at it, rename Ranking.getIndexOfKey to something that
makes more sense.

Bug: 15126927
Change-Id: I02c2087978c6c4ec1198be496c6250a66143ecb3
parent 5b53148a
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -25650,12 +25650,10 @@ package android.service.notification {
    method public final deprecated void cancelNotification(java.lang.String, java.lang.String, int);
    method public final void cancelNotification(java.lang.String);
    method public final void cancelNotifications(java.lang.String[]);
    method public java.lang.String[] getActiveNotificationKeys();
    method public android.service.notification.StatusBarNotification[] getActiveNotifications();
    method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[]);
    method public android.service.notification.NotificationListenerService.Ranking getCurrentRanking();
    method public android.os.IBinder onBind(android.content.Intent);
    method public void onListenerConnected(java.lang.String[]);
    method public void onListenerConnected();
    method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
    method public void onNotificationRankingUpdate();
    method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
@@ -25664,8 +25662,8 @@ package android.service.notification {
  public static class NotificationListenerService.Ranking implements android.os.Parcelable {
    method public int describeContents();
    method public int getIndexOfKey(java.lang.String);
    method public java.lang.String[] getOrderedKeys();
    method public int getRank(java.lang.String);
    method public boolean isAmbient(java.lang.String);
    method public boolean isInterceptedByDoNotDisturb(java.lang.String);
    method public void writeToParcel(android.os.Parcel, int);
+4 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.ITransientNotification;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.net.Uri;
import android.service.notification.Condition;
import android.service.notification.IConditionListener;
@@ -43,6 +44,8 @@ interface INotificationManager
    void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
    boolean areNotificationsEnabledForPackage(String pkg, int uid);

    // TODO: Remove this when callers have been migrated to the equivalent
    // INotificationListener method.
    StatusBarNotification[] getActiveNotifications(String callingPkg);
    StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);

@@ -52,8 +55,7 @@ interface INotificationManager
    void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
    void cancelNotificationsFromListener(in INotificationListener token, in String[] keys);

    StatusBarNotification[] getActiveNotificationsFromListener(in INotificationListener token, in String[] keys);
    String[] getActiveNotificationKeysFromListener(in INotificationListener token);
    ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token);

    ZenModeConfig getZenModeConfig();
    boolean setZenModeConfig(in ZenModeConfig config);
+11 −33
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,6 +31,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

import java.util.List;

/**
 * A service that receives calls from the system when new notifications are
 * posted or removed, or their ranking changed.
@@ -95,12 +98,10 @@ public abstract class NotificationListenerService extends Service {

    /**
     * Implement this method to learn about when the listener is enabled and connected to
     * the notification manager.  You are safe to call {@link #getActiveNotifications(String[])
     * the notification manager.  You are safe to call {@link #getActiveNotifications()}
     * at this time.
     *
     * @param notificationKeys The notification keys for all currently posted notifications.
     */
    public void onListenerConnected(String[] notificationKeys) {
    public void onListenerConnected() {
        // optional
    }

@@ -223,34 +224,12 @@ public abstract class NotificationListenerService extends Service {
     * @return An array of active notifications, sorted in natural order.
     */
    public StatusBarNotification[] getActiveNotifications() {
        return getActiveNotifications(null /*all*/);
    }

    /**
     * Request the list of notification keys in their current ranking order.
     * <p>
     * You can use the notification keys for subsequent retrieval via
     * {@link #getActiveNotifications(String[]) or dismissal via
     * {@link #cancelNotifications(String[]).
     *
     * @return An array of active notification keys, in their ranking order.
     */
    public String[] getActiveNotificationKeys() {
        return mRanking.getOrderedKeys();
    }

    /**
     * Request the list of outstanding notifications (that is, those that are visible to the
     * current user). Useful when you don't know what's already been posted.
     *
     * @param keys A specific list of notification keys, or {@code null} for all.
     * @return An array of active notifications, sorted in natural order
     *   if {@code keys} is {@code null}.
     */
    public StatusBarNotification[] getActiveNotifications(String[] keys) {
        if (!isBound()) return null;
        try {
            return getNotificationInterface().getActiveNotificationsFromListener(mWrapper, keys);
            ParceledListSlice<StatusBarNotification> parceledList =
                    getNotificationInterface().getActiveNotificationsFromListener(mWrapper);
            List<StatusBarNotification> list = parceledList.getList();
            return list.toArray(new StatusBarNotification[list.size()]);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
@@ -359,8 +338,7 @@ public abstract class NotificationListenerService extends Service {
            synchronized (mWrapper) {
                applyUpdate(update);
                try {
                    NotificationListenerService.this.onListenerConnected(
                            mRanking.getOrderedKeys());
                    NotificationListenerService.this.onListenerConnected();
                } catch (Throwable t) {
                    Log.w(TAG, "Error running onListenerConnected", t);
                }
@@ -418,7 +396,7 @@ public abstract class NotificationListenerService extends Service {
         * @return The rank of the notification with the given key; -1 when the
         *      given key is unknown.
         */
        public int getIndexOfKey(String key) {
        public int getRank(String key) {
            // TODO: Optimize.
            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
            for (int i = 0; i < orderedKeys.length; i++) {
+9 −24
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
@@ -1359,18 +1360,16 @@ public class NotificationManagerService extends SystemService {
         * should be used.
         *
         * @param token The binder for the listener, to check that the caller is allowed
         * @param keys the notification keys to fetch, or null for all active notifications.
         * @returns The return value will contain the notifications specified in keys, in that
         *      order, or if keys is null, all the notifications, in natural order.
         */
        @Override
        public StatusBarNotification[] getActiveNotificationsFromListener(
                INotificationListener token, String[] keys) {
        public ParceledListSlice<StatusBarNotification> getActiveNotificationsFromListener(
                INotificationListener token) {
            synchronized (mNotificationList) {
                final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
                final ArrayList<StatusBarNotification> list
                        = new ArrayList<StatusBarNotification>();
                if (keys == null) {
                final int N = mNotificationList.size();
                for (int i=0; i<N; i++) {
                    StatusBarNotification sbn = mNotificationList.get(i).sbn;
@@ -1378,23 +1377,9 @@ public class NotificationManagerService extends SystemService {
                        list.add(sbn);
                    }
                }
                } else {
                    final int N = keys.length;
                    for (int i=0; i<N; i++) {
                        NotificationRecord r = mNotificationsByKey.get(keys[i]);
                        if (r != null && info.enabledAndUserMatches(r.sbn.getUserId())) {
                            list.add(r.sbn);
                        }
                return new ParceledListSlice<StatusBarNotification>(list);
            }
        }
                return list.toArray(new StatusBarNotification[list.size()]);
            }
        }

        @Override
        public String[] getActiveNotificationKeysFromListener(INotificationListener token) {
            return NotificationManagerService.this.getActiveNotificationKeys(token);
        }

        @Override
        public ZenModeConfig getZenModeConfig() {