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

Commit 9473e76d authored by Julia Reynolds's avatar Julia Reynolds Committed by Automerger Merge Worker
Browse files

Merge "Adds an NLS api for telling the OS what notifs types they bridge" into sc-dev am: 5db5a6ae

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13700910

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I888027570ed9f159b4c8ce55c670f161b2385599
parents e8beb25f 5db5a6ae
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -38075,6 +38075,7 @@ package android.service.notification {
    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
    field public static final String META_DATA_DEFAULT_FILTER_TYPES = "android.service.notification.default_filter_types";
    field public static final String META_DATA_DISABLED_FILTER_TYPES = "android.service.notification.disabled_filter_types";
    field public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1; // 0x1
    field public static final int NOTIFICATION_CHANNEL_OR_GROUP_DELETED = 3; // 0x3
    field public static final int NOTIFICATION_CHANNEL_OR_GROUP_UPDATED = 2; // 0x2
+17 −0
Original line number Diff line number Diff line
@@ -85,6 +85,10 @@ import java.util.Objects;
 *               android:name="android.service.notification.default_filter_types"
 *               android:value="1,2">
 *           </meta-data>
 *     <meta-data
 *               android:name="android.service.notification.disabled_filter_types"
 *               android:value="2">
 *           </meta-data>
 * &lt;/service></pre>
 *
 * <p>The service should wait for the {@link #onListenerConnected()} event
@@ -122,6 +126,19 @@ public abstract class NotificationListenerService extends Service {
    public static final String META_DATA_DEFAULT_FILTER_TYPES
            = "android.service.notification.default_filter_types";

    /**
     * The name of the {@code meta-data} tag containing a comma separated list of default
     * integer notification types that this listener never wants to receive. See
     * {@link #FLAG_FILTER_TYPE_ONGOING},
     * {@link #FLAG_FILTER_TYPE_CONVERSATIONS}, {@link #FLAG_FILTER_TYPE_ALERTING),
     * and {@link #FLAG_FILTER_TYPE_SILENT}.
     * <p>Types provided in this list will appear as 'off' and 'disabled' in the user interface,
     * so users don't enable a type that the listener will never bridge to their paired devices.</p>
     *
     */
    public static final String META_DATA_DISABLED_FILTER_TYPES
            = "android.service.notification.disabled_filter_types";

    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Normal interruption filter.
+42 −19
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ import static android.service.notification.NotificationListenerService.FLAG_FILT
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS;
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS;
import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES;
import static android.service.notification.NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
@@ -9894,13 +9896,39 @@ public class NotificationManagerService extends SystemService {
            Pair listener = Pair.create(si.getComponentName(), userId);
            NotificationListenerFilter existingNlf =
                    mRequestedNotificationListeners.get(listener);
            if (si.metaData != null) {
                if (existingNlf  == null) {
                    // no stored filters for this listener; see if they provided a default
                if (si.metaData != null) {
                    String typeList = si.metaData.getString(
                            NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES);
                    if (si.metaData.containsKey(META_DATA_DEFAULT_FILTER_TYPES)) {
                        String typeList =
                                si.metaData.get(META_DATA_DEFAULT_FILTER_TYPES).toString();
                        if (typeList != null) {
                            int types = getTypesFromStringList(typeList);
                            NotificationListenerFilter nlf =
                                    new NotificationListenerFilter(types, new ArraySet<>());
                            mRequestedNotificationListeners.put(listener, nlf);
                        }
                    }
                }

                // also check the types they never want bridged
                if (si.metaData.containsKey(META_DATA_DISABLED_FILTER_TYPES)) {
                    int neverBridge = getTypesFromStringList(si.metaData.get(
                            META_DATA_DISABLED_FILTER_TYPES).toString());
                    if (neverBridge != 0) {
                        NotificationListenerFilter nlf =
                                mRequestedNotificationListeners.getOrDefault(
                                        listener, new NotificationListenerFilter());
                        nlf.setTypes(nlf.getTypes() & ~neverBridge);
                        mRequestedNotificationListeners.put(listener, nlf);
                    }
                }
            }
        }

        private int getTypesFromStringList(String typeList) {
            int types = 0;
            if (typeList != null) {
                String[] typeStrings = typeList.split(XML_SEPARATOR);
                for (int i = 0; i < typeStrings.length; i++) {
                    if (TextUtils.isEmpty(typeStrings[i])) {
@@ -9912,13 +9940,8 @@ public class NotificationManagerService extends SystemService {
                        // skip
                    }
                }

                         NotificationListenerFilter nlf =
                                 new NotificationListenerFilter(types, new ArraySet<>());
                        mRequestedNotificationListeners.put(listener, nlf);
                    }
                }
            }
            return types;
        }

        @GuardedBy("mNotificationLock")
+48 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ package com.android.server.notification;

import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;

import static com.android.server.notification.NotificationManagerService.NotificationListeners.TAG_REQUESTED_LISTENERS;

@@ -204,6 +206,52 @@ public class NotificationListenersTest extends UiServiceTestCase {
                .isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ALERTING);
    }

    @Test
    public void testEnsureFilters_newServiceWithMetadata_onlyOneListed() {
        ServiceInfo si = new ServiceInfo();
        si.packageName = "new";
        si.name = "comp";
        si.metaData = new Bundle();
        si.metaData.putInt(NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES, 2);

        mListeners.ensureFilters(si, 0);

        assertThat(mListeners.getNotificationListenerFilter(
                Pair.create(si.getComponentName(), 0)).getTypes())
                .isEqualTo(FLAG_FILTER_TYPE_ALERTING);
    }

    @Test
    public void testEnsureFilters_newServiceWithMetadata_disabledTypes() {
        ServiceInfo si = new ServiceInfo();
        si.packageName = "new";
        si.name = "comp";
        si.metaData = new Bundle();
        si.metaData.putString(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES, "1,2");

        mListeners.ensureFilters(si, 0);

        assertThat(mListeners.getNotificationListenerFilter(
                Pair.create(si.getComponentName(), 0)).getTypes())
                .isEqualTo(FLAG_FILTER_TYPE_SILENT | FLAG_FILTER_TYPE_ONGOING);
    }

    @Test
    public void testEnsureFilters_newServiceWithMetadata_metaDataDisagrees() {
        ServiceInfo si = new ServiceInfo();
        si.packageName = "new";
        si.name = "comp";
        si.metaData = new Bundle();
        si.metaData.putString(NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES, "1,2");
        si.metaData.putInt(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES, 1);

        mListeners.ensureFilters(si, 0);

        assertThat(mListeners.getNotificationListenerFilter(
                Pair.create(si.getComponentName(), 0)).getTypes())
                .isEqualTo(FLAG_FILTER_TYPE_ALERTING);
    }

    @Test
    public void testEnsureFilters_newServiceWithEmptyMetadata() {
        ServiceInfo si = new ServiceInfo();