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

Commit ab98ee87 authored by Chris Wren's avatar Chris Wren Committed by Android (Google) Code Review
Browse files

Merge "implement onNotificationEnqueued callback"

parents ac7c606c 47633425
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;
    }
}