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

Commit 0e36d959 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Allow apps to migrate NLS filter settings

On a per user vs manifest wide basis.

Test: atest, cts-verifier
Bug: 184027330
Change-Id: Iae591765e410e360f289692bac012a1f26574add
parent 68558761
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -38527,6 +38527,7 @@ package android.service.notification {
    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(@NonNull String, @NonNull android.os.UserHandle);
    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(@NonNull String, @NonNull android.os.UserHandle);
    method public final android.service.notification.StatusBarNotification[] getSnoozedNotifications();
    method public final void migrateNotificationFilter(int, @Nullable java.util.List<java.lang.String>);
    method public android.os.IBinder onBind(android.content.Intent);
    method public void onInterruptionFilterChanged(int);
    method public void onListenerConnected();
+1 −0
Original line number Diff line number Diff line
@@ -227,6 +227,7 @@ interface INotificationManager

    NotificationListenerFilter getListenerFilter(in ComponentName cn, int userId);
    void setListenerFilter(in ComponentName cn, int userId, in NotificationListenerFilter nlf);
    void migrateNotificationFilter(in INotificationListener token, int defaultTypes, in List<String> disallowedPkgs);

    void setToastRateLimitingEnabled(boolean enable);
}
+10 −4
Original line number Diff line number Diff line
@@ -31,15 +31,17 @@ import android.util.ArraySet;
 * @hide
 */
public class NotificationListenerFilter implements Parcelable {

    private static final int DEFAULT_TYPES = FLAG_FILTER_TYPE_CONVERSATIONS
            | FLAG_FILTER_TYPE_ALERTING
            | FLAG_FILTER_TYPE_SILENT
            | FLAG_FILTER_TYPE_ONGOING;
    private int mAllowedNotificationTypes;
    // VersionedPackage is holding the pkg name and pkg uid
    private ArraySet<VersionedPackage> mDisallowedPackages;

    public NotificationListenerFilter() {
        mAllowedNotificationTypes = FLAG_FILTER_TYPE_CONVERSATIONS
                | FLAG_FILTER_TYPE_ALERTING
                | FLAG_FILTER_TYPE_SILENT
                | FLAG_FILTER_TYPE_ONGOING;
        mAllowedNotificationTypes = DEFAULT_TYPES;
        mDisallowedPackages = new ArraySet<>();
    }

@@ -80,6 +82,10 @@ public class NotificationListenerFilter implements Parcelable {
        return (mAllowedNotificationTypes & type) != 0;
    }

    public boolean areAllTypesAllowed() {
        return DEFAULT_TYPES == mAllowedNotificationTypes;
    }

    public boolean isPackageAllowed(VersionedPackage pkg) {
        return !mDisallowedPackages.contains(pkg);
    }
+23 −0
Original line number Diff line number Diff line
@@ -792,6 +792,29 @@ public abstract class NotificationListenerService extends Service {
        }
    }

    /**
     * Lets an app migrate notification filters from its app into the OS.
     *
     * <p>This call will be ignored if the app has already migrated these settings or the user
     * has set filters in the UI. This method is intended for user specific settings; if an app has
     * already specified defaults types in its manifest with
     * {@link #META_DATA_DEFAULT_FILTER_TYPES}, the defaultTypes option will be ignored.</p>
     * @param defaultTypes A value representing the types of notifications that this listener should
     * receive by default
     * @param disallowedPkgs A list of package names whose notifications should not be seen by this
     * listener, by default, because the listener does not process or display them, or because a
     * user had previously disallowed these packages in the listener app's UI
     */
    public final void migrateNotificationFilter(@NotificationFilterTypes int defaultTypes,
            @Nullable List<String> disallowedPkgs) {
        if (!isBound()) return;
        try {
            getNotificationInterface().migrateNotificationFilter(
                    mWrapper, defaultTypes, disallowedPkgs);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Inform the notification manager that these notifications have been viewed by the
+44 −1
Original line number Diff line number Diff line
@@ -4327,6 +4327,49 @@ public class NotificationManagerService extends SystemService {
            }
        }

        /**
         * Allows an app to set an initial notification listener filter
         *
         * @param token The binder for the listener, to check that the caller is allowed
         */
        @Override
        public void migrateNotificationFilter(INotificationListener token, int defaultTypes,
                List<String> disallowedApps) {
            final long identity = Binder.clearCallingIdentity();
            try {
                synchronized (mNotificationLock) {
                    final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);

                    Pair key = Pair.create(info.component, info.userid);

                    NotificationListenerFilter nlf = mListeners.getNotificationListenerFilter(key);
                    if (nlf == null) {
                        nlf = new NotificationListenerFilter();
                    }
                    if (nlf.getDisallowedPackages().isEmpty() && disallowedApps != null) {
                        for (String pkg : disallowedApps) {
                            // block the current user's version and any work profile versions
                            for (int userId : mUm.getProfileIds(info.userid, false)) {
                                try {
                                    int uid = getUidForPackageAndUser(pkg, UserHandle.of(userId));
                                    VersionedPackage vp = new VersionedPackage(pkg, uid);
                                    nlf.addPackage(vp);
                                } catch (Exception e) {
                                    // pkg doesn't exist on that user; skip
                                }
                            }
                        }
                    }
                    if (nlf.areAllTypesAllowed()) {
                        nlf.setTypes(defaultTypes);
                    }
                    mListeners.setNotificationListenerFilter(key, nlf);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }

        /**
         * Allow an INotificationListener to simulate clearing (dismissing) a single notification.
         *
@@ -5225,7 +5268,7 @@ public class NotificationManagerService extends SystemService {
        }

        private int getUidForPackageAndUser(String pkg, UserHandle user) throws RemoteException {
            int uid = 0;
            int uid = INVALID_UID;
            final long identity = Binder.clearCallingIdentity();
            try {
                uid = mPackageManager.getPackageUid(pkg, 0, user.getIdentifier());
Loading