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

Commit 47633425 authored by Chris Wren's avatar Chris Wren
Browse files

implement onNotificationEnqueued callback

Bug: 22455414
Change-Id: I9dafc7b8cbf0268b28d9e9fb0cae9c3b451be52c
parent 2d050942
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -297,7 +297,6 @@ abstract public class ManagedServices {
        checkType(guest.service);
        if (registerServiceImpl(guest) != null) {
            onServiceAdded(guest);
            onServiceAdded(guest);
        }
    }

+192 −104
Original line number Diff line number Diff line
@@ -223,6 +223,8 @@ public class NotificationManagerService extends SystemService {
    private WorkerHandler mHandler;
    private final HandlerThread mRankingThread = new HandlerThread("ranker",
            Process.THREAD_PRIORITY_BACKGROUND);
    private final HandlerThread mAssistantThread = new HandlerThread("assistant",
            Process.THREAD_PRIORITY_BACKGROUND);

    private Light mNotificationLight;
    Light mAttentionLight;
@@ -295,6 +297,7 @@ public class NotificationManagerService extends SystemService {
    private static final int MY_UID = Process.myUid();
    private static final int MY_PID = Process.myPid();
    private RankingHandler mRankingHandler;
    private Handler mAssistantHandler;

    private static class Archive {
        final int mBufferSize;
@@ -878,6 +881,7 @@ public class NotificationManagerService extends SystemService {

        mHandler = new WorkerHandler();
        mRankingThread.start();
        mAssistantThread.start();
        String[] extractorNames;
        try {
            extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -886,6 +890,7 @@ public class NotificationManagerService extends SystemService {
        }
        mUsageStats = new NotificationUsageStats(getContext());
        mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
        mAssistantHandler = new Handler(mAssistantThread.getLooper());
        mRankingHelper = new RankingHelper(getContext(),
                mRankingHandler,
                mUsageStats,
@@ -1957,7 +1962,7 @@ public class NotificationManagerService extends SystemService {

        @Override
        public void setImportanceFromAssistant(INotificationListener token, String key,
                int importance, CharSequence explanation) {
                int importance, CharSequence explanation) throws RemoteException {
            final long identity = Binder.clearCallingIdentity();
            try {
                synchronized (mNotificationList) {
@@ -2249,12 +2254,6 @@ public class NotificationManagerService extends SystemService {
                    + " id=" + id + " notification=" + notification);
        }

        mHandler.post(new Runnable() {
            @Override
            public void run() {

                synchronized (mNotificationList) {

        // Sanitize inputs
        notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
                Notification.PRIORITY_MAX);
@@ -2263,18 +2262,48 @@ public class NotificationManagerService extends SystemService {
        final StatusBarNotification n = new StatusBarNotification(
                pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
                user);
                    NotificationRecord r = new NotificationRecord(getContext(), n);
        final NotificationRecord r = new NotificationRecord(getContext(), n);
        mHandler.post(new EnqueueNotificationRunnable(userId, r));

        idOut[0] = id;
    }

    private class EnqueueNotificationRunnable implements Runnable {
        private final NotificationRecord r;
        private final int userId;

        EnqueueNotificationRunnable(int userId, NotificationRecord r) {
            this.userId = userId;
            this.r = r;
        };

        @Override
        public void run() {

            synchronized (mNotificationList) {
                final StatusBarNotification n = r.sbn;
                Slog.d(TAG, "EnqueueNotificationRunnable.run for: " + n.getKey());
                NotificationRecord old = mNotificationsByKey.get(n.getKey());
                if (old != null) {
                    // Retain ranking information from previous record
                    r.copyRankingInformation(old);
                }

                final int callingUid = n.getUid();
                final int callingPid = n.getInitialPid();
                final Notification notification = n.getNotification();
                final String pkg = n.getPackageName();
                final int id = n.getId();
                final String tag = n.getTag();
                final boolean isSystemNotification = isUidSystem(callingUid) ||
                        ("android".equals(pkg));

                // Handle grouped notifications and bail out early if we
                // can to avoid extracting signals.
                handleGroupedNotificationLocked(r, old, callingUid, callingPid);
                boolean ignoreNotification =
                        removeUnusedGroupedNotificationLocked(r, old, callingUid, callingPid);
                Slog.d(TAG, "ignoreNotification is " + ignoreNotification);

                // This conditional is a dirty hack to limit the logging done on
                //     behalf of the download manager without affecting other apps.
@@ -2296,6 +2325,8 @@ public class NotificationManagerService extends SystemService {
                }

                mRankingHelper.extractSignals(r);

                // why is this here?
                savePolicyFile();

                // blocked apps/topics
@@ -2309,6 +2340,13 @@ public class NotificationManagerService extends SystemService {
                    }
                }

                // tell the assistant about the notification
                if (mAssistant.isEnabled()) {
                    mAssistant.onNotificationEnqueued(r);
                    // TODO delay the code below here for 100ms or until there is an answer
                }


                int index = indexOfNotificationLocked(n.getKey());
                if (index < 0) {
                    mNotificationList.add(r);
@@ -2353,9 +2391,6 @@ public class NotificationManagerService extends SystemService {
                buzzBeepBlinkLocked(r);
            }
        }
        });

        idOut[0] = id;
    }

    /**
@@ -3391,6 +3426,30 @@ public class NotificationManagerService extends SystemService {
        return true;
    }

    private class TrimCache {
        StatusBarNotification heavy;
        StatusBarNotification sbnClone;
        StatusBarNotification sbnCloneLight;

        TrimCache(StatusBarNotification sbn) {
            heavy = sbn;
        }

        StatusBarNotification ForListener(ManagedServiceInfo info) {
            if (mListeners.getOnNotificationPostedTrim(info) == TRIM_LIGHT) {
                if (sbnCloneLight == null) {
                    sbnCloneLight = heavy.cloneLight();
                }
                return sbnCloneLight;
            } else {
                if (sbnClone == null) {
                    sbnClone = heavy.clone();
                }
                return sbnClone;
            }
        }
    }

    public class NotificationAssistant extends ManagedServices {

        public NotificationAssistant() {
@@ -3428,6 +3487,46 @@ public class NotificationManagerService extends SystemService {
        protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
            mListeners.unregisterService(removed.service, removed.userid);
        }

        public void onNotificationEnqueued(final NotificationRecord r) {
            final StatusBarNotification sbn = r.sbn;
            TrimCache trimCache = new TrimCache(sbn);

            // mServices is the list inside ManagedServices of all the assistants,
            // There should be only one, but it's a list, so while we enforce
            // singularity elsewhere, we keep it general here, to avoid surprises.
            for (final ManagedServiceInfo info : NotificationAssistant.this.mServices) {
                boolean sbnVisible = isVisibleToListener(sbn, info);
                if (!sbnVisible) {
                    continue;
                }

                final int importance = r.getImportance();
                final boolean fromUser = r.isImportanceFromUser();
                final StatusBarNotification sbnToPost =  trimCache.ForListener(info);
                mAssistantHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        notifyEnqueued(info, sbnToPost, importance, fromUser);
                    }
                });
            }
        }

        private void notifyEnqueued(final ManagedServiceInfo info,
                final StatusBarNotification sbn, int importance, boolean fromUser) {
            final INotificationListener assistant = (INotificationListener) info.service;
            StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
            try {
                assistant.onNotificationEnqueued(sbnHolder, importance, fromUser);
            } catch (RemoteException ex) {
                Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
            }
        }

        public boolean isEnabled() {
            return !mServices.isEmpty();
        }
    }

    public class NotificationListeners extends ManagedServices {
@@ -3476,7 +3575,6 @@ public class NotificationManagerService extends SystemService {
            }
        }


        @Override
        protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
            if (mListenersDisablingEffects.remove(removed)) {
@@ -3508,8 +3606,7 @@ public class NotificationManagerService extends SystemService {
         */
        public void notifyPostedLocked(StatusBarNotification sbn, StatusBarNotification oldSbn) {
            // Lazily initialized snapshots of the notification.
            StatusBarNotification sbnClone = null;
            StatusBarNotification sbnCloneLight = null;
            TrimCache trimCache = new TrimCache(sbn);

            for (final ManagedServiceInfo info : mServices) {
                boolean sbnVisible = isVisibleToListener(sbn, info);
@@ -3532,16 +3629,7 @@ public class NotificationManagerService extends SystemService {
                    continue;
                }

                final int trim = mListeners.getOnNotificationPostedTrim(info);

                if (trim == TRIM_LIGHT && sbnCloneLight == null) {
                    sbnCloneLight = sbn.cloneLight();
                } else if (trim == TRIM_FULL && sbnClone == null) {
                    sbnClone = sbn.clone();
                }
                final StatusBarNotification sbnToPost =
                        (trim == TRIM_FULL) ? sbnClone : sbnCloneLight;

                final StatusBarNotification sbnToPost =  trimCache.ForListener(info);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
+7 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.server.notification;

import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_LOW;
@@ -88,8 +89,8 @@ public final class NotificationRecord {
    private int mAuthoritativeRank;
    private String mGlobalSortKey;
    private int mPackageVisibility;
    private int mTopicImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
    private int mImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
    private int mTopicImportance = IMPORTANCE_UNSPECIFIED;
    private int mImportance = IMPORTANCE_UNSPECIFIED;
    private CharSequence mImportanceExplanation = null;

    private int mSuppressedVisualEffects = 0;
@@ -510,4 +511,8 @@ public final class NotificationRecord {
    public String getGroupKey() {
        return sbn.getGroupKey();
    }

    public boolean isImportanceFromUser() {
        return mImportance == mTopicImportance;
    }
}