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

Commit 45c0d583 authored by Christoph Studer's avatar Christoph Studer Committed by Android (Google) Code Review
Browse files

Merge "NoListener: Factor out ZEN mode API" into lmp-dev

parents 7e7f9a3f 85a384b4
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -27104,9 +27104,11 @@ package android.service.notification {
    method public final void cancelNotifications(java.lang.String[]);
    method public android.service.notification.StatusBarNotification[] getActiveNotifications();
    method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[]);
    method public final int getCurrentInterruptionFilter();
    method public final int getCurrentListenerHints();
    method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
    method public android.os.IBinder onBind(android.content.Intent);
    method public void onInterruptionFilterChanged(int);
    method public void onListenerConnected();
    method public void onListenerHintsChanged(int);
    method public void onNotificationPosted(android.service.notification.StatusBarNotification);
@@ -27114,13 +27116,12 @@ package android.service.notification {
    method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
    method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
    method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
    method public final void requestInterruptionFilter(int);
    method public final void requestListenerHints(int);
    field public static final int HINTS_NONE = 0; // 0x0
    field public static final int HINT_HOST_DISABLE_EFFECTS = 4; // 0x4
    field public static final int HINT_HOST_INTERRUPTION_LEVEL_ALL = 1; // 0x1
    field public static final int HINT_HOST_INTERRUPTION_LEVEL_NONE = 3; // 0x3
    field public static final int HINT_HOST_INTERRUPTION_LEVEL_PRIORITY = 2; // 0x2
    field public static final int HOST_INTERRUPTION_LEVEL_MASK = 3; // 0x3
    field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
    field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
  }
+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ interface INotificationManager
    ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token, in String[] keys);
    void requestHintsFromListener(in INotificationListener token, int hints);
    int getHintsFromListener(in INotificationListener token);
    void requestInterruptionFilterFromListener(in INotificationListener token, int interruptionFilter);
    int getInterruptionFilterFromListener(in INotificationListener token);

    ComponentName getEffectsSuppressor();

+2 −1
Original line number Diff line number Diff line
@@ -29,4 +29,5 @@ oneway interface INotificationListener
            in NotificationRankingUpdate update);
    void onNotificationRankingUpdate(in NotificationRankingUpdate update);
    void onListenerHintsChanged(int hints);
    void onInterruptionFilterChanged(int interruptionFilter);
}
+89 −19
Original line number Diff line number Diff line
@@ -58,26 +58,28 @@ public abstract class NotificationListenerService extends Service {
    private final String TAG = NotificationListenerService.class.getSimpleName()
            + "[" + getClass().getSimpleName() + "]";

    /** {@link #getCurrentListenerHints() Listener hints} constant - default state. */
    public static final int HINTS_NONE = 0;

    /** Bitmask range for {@link #getCurrentListenerHints() Listener hints} host interruption level
     * constants.  */
    public static final int HOST_INTERRUPTION_LEVEL_MASK = 0x3;

    /** {@link #getCurrentListenerHints() Listener hints} constant - Normal interruption level. */
    public static final int HINT_HOST_INTERRUPTION_LEVEL_ALL = 1;
    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Normal interruption filter.
     */
    public static final int INTERRUPTION_FILTER_ALL = 1;

    /** {@link #getCurrentListenerHints() Listener hints} constant - Priority interruption level. */
    public static final int HINT_HOST_INTERRUPTION_LEVEL_PRIORITY = 2;
    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Priority interruption filter.
     */
    public static final int INTERRUPTION_FILTER_PRIORITY = 2;

    /** {@link #getCurrentListenerHints() Listener hints} constant - No interruptions level. */
    public static final int HINT_HOST_INTERRUPTION_LEVEL_NONE = 3;
    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     No interruptions filter.
     */
    public static final int INTERRUPTION_FILTER_NONE = 3;

    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
     * should disable notification sound, vibrating and other visual or aural effects.
     * This does not change the interruption level, only the effects. **/
    public static final int HINT_HOST_DISABLE_EFFECTS = 1 << 2;
     * This does not change the interruption filter, only the effects. **/
    public static final int HINT_HOST_DISABLE_EFFECTS = 1;

    private INotificationListenerWrapper mWrapper = null;
    private RankingMap mRankingMap;
@@ -197,6 +199,17 @@ public abstract class NotificationListenerService extends Service {
        // optional
    }

    /**
     * Implement this method to be notified when the
     * {@link #getCurrentInterruptionFilter() interruption filter} changed.
     *
     * @param interruptionFilter The current
     *     {@link #getCurrentInterruptionFilter() interruption filter}.
     */
    public void onInterruptionFilterChanged(int interruptionFilter) {
        // optional
    }

    private final INotificationManager getNotificationInterface() {
        if (mNoMan == null) {
            mNoMan = INotificationManager.Stub.asInterface(
@@ -345,15 +358,42 @@ public abstract class NotificationListenerService extends Service {
     * shared across all listeners or a feature the notification host does not support or refuses
     * to grant.
     *
     * @return One or more of the HINT_ constants.
     * @return Zero or more of the HINT_ constants.
     */
    public final int getCurrentListenerHints() {
        if (!isBound()) return HINTS_NONE;
        if (!isBound()) return 0;
        try {
            return getNotificationInterface().getHintsFromListener(mWrapper);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
            return 0;
        }
    }

    /**
     * Gets the current notification interruption filter active on the host.
     *
     * <p>
     * The interruption filter defines which notifications are allowed to interrupt the user
     * (e.g. via sound &amp; vibration) and is applied globally. Listeners can find out whether
     * a specific notification matched the interruption filter via
     * {@link Ranking#matchesInterruptionFilter()}.
     * <p>
     * The current filter may differ from the previously requested filter if the notification host
     * does not support or refuses to apply the requested filter, or if another component changed
     * the filter in the meantime.
     * <p>
     * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
     *
     * @return One of the INTERRUPTION_FILTER_ constants, or 0 on errors.
     */
    public final int getCurrentInterruptionFilter() {
        if (!isBound()) return 0;
        try {
            return getNotificationInterface().getHintsFromListener(mWrapper);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
            return HINTS_NONE;
            return 0;
        }
    }

@@ -361,7 +401,7 @@ public abstract class NotificationListenerService extends Service {
     * Sets the desired {@link #getCurrentListenerHints() listener hints}.
     *
     * <p>
     * This is merely a request, the host may or not choose to take action depending
     * This is merely a request, the host may or may not choose to take action depending
     * on other listener requests or other global state.
     * <p>
     * Listen for updates using {@link #onListenerHintsChanged(int)}.
@@ -377,6 +417,27 @@ public abstract class NotificationListenerService extends Service {
        }
    }

    /**
     * Sets the desired {@link #getCurrentInterruptionFilter() interruption filter}.
     *
     * <p>
     * This is merely a request, the host may or may not choose to apply the requested
     * interruption filter depending on other listener requests or other global state.
     * <p>
     * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
     *
     * @param interruptionFilter One of the INTERRUPTION_FILTER_ constants.
     */
    public final void requestInterruptionFilter(int interruptionFilter) {
        if (!isBound()) return;
        try {
            getNotificationInterface()
                    .requestInterruptionFilterFromListener(mWrapper, interruptionFilter);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Returns current ranking information.
     *
@@ -514,6 +575,15 @@ public abstract class NotificationListenerService extends Service {
                Log.w(TAG, "Error running onListenerHintsChanged", t);
            }
        }

        @Override
        public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException {
            try {
                NotificationListenerService.this.onInterruptionFilterChanged(interruptionFilter);
            } catch (Throwable t) {
                Log.w(TAG, "Error running onInterruptionFilterChanged", t);
            }
        }
    }

    private void applyUpdate(NotificationRankingUpdate update) {
+75 −5
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -127,6 +126,7 @@ public class NotificationManagerService extends SystemService {
    static final int MESSAGE_RANKING_CONFIG_CHANGE = 5;
    static final int MESSAGE_SEND_RANKING_UPDATE = 6;
    static final int MESSAGE_LISTENER_HINTS_CHANGED = 7;
    static final int MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED = 8;

    static final int LONG_DELAY = 3500; // 3.5 seconds
    static final int SHORT_DELAY = 2000; // 2 seconds
@@ -178,6 +178,7 @@ public class NotificationManagerService extends SystemService {
    private final ArraySet<ManagedServiceInfo> mListenersDisablingEffects = new ArraySet<>();
    private ComponentName mEffectsSuppressor;
    private int mListenerHints;  // right now, all hints are global
    private int mInterruptionFilter;  // current ZEN mode as communicated to listeners

    // for enabling and disabling notification pulse behavior
    private boolean mScreenOn = true;
@@ -806,7 +807,7 @@ public class NotificationManagerService extends SystemService {
            @Override
            void onZenModeChanged() {
                synchronized(mNotificationList) {
                    updateListenerHintsLocked();
                    updateInterruptionFilterLocked();
                }
            }
        });
@@ -938,8 +939,7 @@ public class NotificationManagerService extends SystemService {
    }

    private void updateListenerHintsLocked() {
        final int hints = (mListenersDisablingEffects.isEmpty() ? 0 : HINT_HOST_DISABLE_EFFECTS) |
                mZenModeHelper.getZenModeListenerHint();
        final int hints = mListenersDisablingEffects.isEmpty() ? 0 : HINT_HOST_DISABLE_EFFECTS;
        if (hints == mListenerHints) return;
        mListenerHints = hints;
        scheduleListenerHintsChanged(hints);
@@ -954,6 +954,13 @@ public class NotificationManagerService extends SystemService {
                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
    }

    private void updateInterruptionFilterLocked() {
        int interruptionFilter = mZenModeHelper.getZenModeListenerInterruptionFilter();
        if (interruptionFilter == mInterruptionFilter) return;
        mInterruptionFilter = interruptionFilter;
        scheduleInterruptionFilterChanged(interruptionFilter);
    }

    private final IBinder mService = new INotificationManager.Stub() {
        // Toasts
        // ============================================================================
@@ -1318,7 +1325,6 @@ public class NotificationManagerService extends SystemService {
                    } else {
                        mListenersDisablingEffects.remove(info);
                    }
                    mZenModeHelper.requestFromListener(hints);
                    updateListenerHintsLocked();
                    updateEffectsSuppressorLocked();
                }
@@ -1334,6 +1340,29 @@ public class NotificationManagerService extends SystemService {
            }
        }

        @Override
        public void requestInterruptionFilterFromListener(INotificationListener token,
                int interruptionFilter) throws RemoteException {
            final long identity = Binder.clearCallingIdentity();
            try {
                synchronized (mNotificationList) {
                    mListeners.checkServiceTokenLocked(token);
                    mZenModeHelper.requestFromListener(interruptionFilter);
                    updateInterruptionFilterLocked();
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }

        @Override
        public int getInterruptionFilterFromListener(INotificationListener token)
                throws RemoteException {
            synchronized (mNotificationLight) {
                return mInterruptionFilter;
            }
        }

        @Override
        public ZenModeConfig getZenModeConfig() {
            enforceSystemOrSystemUI("INotificationManager.getZenModeConfig");
@@ -2058,12 +2087,26 @@ public class NotificationManagerService extends SystemService {
        mHandler.obtainMessage(MESSAGE_LISTENER_HINTS_CHANGED, state, 0).sendToTarget();
    }

    private void scheduleInterruptionFilterChanged(int listenerInterruptionFilter) {
        mHandler.removeMessages(MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED);
        mHandler.obtainMessage(
                MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED,
                listenerInterruptionFilter,
                0).sendToTarget();
    }

    private void handleListenerHintsChanged(int hints) {
        synchronized (mNotificationList) {
            mListeners.notifyListenerHintsChangedLocked(hints);
        }
    }

    private void handleListenerInterruptionFilterChanged(int interruptionFilter) {
        synchronized (mNotificationList) {
            mListeners.notifyInterruptionFilterChanged(interruptionFilter);
        }
    }

    private final class WorkerHandler extends Handler
    {
        @Override
@@ -2083,6 +2126,9 @@ public class NotificationManagerService extends SystemService {
                case MESSAGE_LISTENER_HINTS_CHANGED:
                    handleListenerHintsChanged(msg.arg1);
                    break;
                case MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED:
                    handleListenerInterruptionFilterChanged(msg.arg1);
                    break;
            }
        }

@@ -2701,6 +2747,20 @@ public class NotificationManagerService extends SystemService {
            }
        }

        public void notifyInterruptionFilterChanged(final int interruptionFilter) {
            for (final ManagedServiceInfo serviceInfo : mServices) {
                if (!serviceInfo.isEnabledForCurrentProfiles()) {
                    continue;
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        notifyInterruptionFilterChanged(serviceInfo, interruptionFilter);
                    }
                });
            }
        }

        private void notifyPosted(final ManagedServiceInfo info,
                final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
            final INotificationListener listener = (INotificationListener)info.service;
@@ -2743,6 +2803,16 @@ public class NotificationManagerService extends SystemService {
            }
        }

        private void notifyInterruptionFilterChanged(ManagedServiceInfo info,
                int interruptionFilter) {
            final INotificationListener listener = (INotificationListener) info.service;
            try {
                listener.onInterruptionFilterChanged(interruptionFilter);
            } catch (RemoteException ex) {
                Log.e(TAG, "unable to notify listener (interruption filter): " + listener, ex);
            }
        }

        private boolean isListenerPackage(String packageName) {
            if (packageName == null) {
                return false;
Loading