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

Commit 8cc6496b authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Store uids in listener filters" into sc-dev

parents fa9d715b a77f0597
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.service.notification.NotificationListenerService.FLAG_FILT
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;

import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
@@ -31,7 +32,7 @@ import android.util.ArraySet;
 */
public class NotificationListenerFilter implements Parcelable {
    private int mAllowedNotificationTypes;
    private ArraySet<String> mDisallowedPackages;
    private ArraySet<VersionedPackage> mDisallowedPackages;

    public NotificationListenerFilter() {
        mAllowedNotificationTypes = FLAG_FILTER_TYPE_CONVERSATIONS
@@ -41,7 +42,7 @@ public class NotificationListenerFilter implements Parcelable {
        mDisallowedPackages = new ArraySet<>();
    }

    public NotificationListenerFilter(int types, ArraySet<String> pkgs) {
    public NotificationListenerFilter(int types, ArraySet<VersionedPackage> pkgs) {
        mAllowedNotificationTypes = types;
        mDisallowedPackages = pkgs;
    }
@@ -51,7 +52,8 @@ public class NotificationListenerFilter implements Parcelable {
     */
    protected NotificationListenerFilter(Parcel in) {
        mAllowedNotificationTypes = in.readInt();
        mDisallowedPackages = (ArraySet<String>) in.readArraySet(String.class.getClassLoader());
        mDisallowedPackages = (ArraySet<VersionedPackage>) in.readArraySet(
                VersionedPackage.class.getClassLoader());
    }

    @Override
@@ -77,7 +79,7 @@ public class NotificationListenerFilter implements Parcelable {
        return (mAllowedNotificationTypes & type) != 0;
    }

    public boolean isPackageAllowed(String pkg) {
    public boolean isPackageAllowed(VersionedPackage pkg) {
        return !mDisallowedPackages.contains(pkg);
    }

@@ -85,7 +87,7 @@ public class NotificationListenerFilter implements Parcelable {
        return mAllowedNotificationTypes;
    }

    public ArraySet<String> getDisallowedPackages() {
    public ArraySet<VersionedPackage> getDisallowedPackages() {
        return mDisallowedPackages;
    }

@@ -93,10 +95,18 @@ public class NotificationListenerFilter implements Parcelable {
        mAllowedNotificationTypes = types;
    }

    public void setDisallowedPackages(ArraySet<String> pkgs) {
    public void setDisallowedPackages(ArraySet<VersionedPackage> pkgs) {
        mDisallowedPackages = pkgs;
    }

    public void removePackage(VersionedPackage pkg) {
        mDisallowedPackages.remove(pkg);
    }

    public void addPackage(VersionedPackage pkg) {
        mDisallowedPackages.add(pkg);
    }

    @Override
    public int describeContents() {
        return 0;
+25 −17
Original line number Diff line number Diff line
@@ -16,14 +16,14 @@

package android.service.notification;

import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
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.google.common.truth.Truth.assertThat;

import android.app.NotificationChannel;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.util.ArraySet;

@@ -45,16 +45,19 @@ public class NotificationListenerFilterTest {
        assertThat(nlf.isTypeAllowed(FLAG_FILTER_TYPE_SILENT)).isTrue();
        assertThat(nlf.getTypes()).isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS
                | FLAG_FILTER_TYPE_ALERTING
                | FLAG_FILTER_TYPE_SILENT);
                | FLAG_FILTER_TYPE_SILENT
                | FLAG_FILTER_TYPE_ONGOING);

        assertThat(nlf.getDisallowedPackages()).isEmpty();
        assertThat(nlf.isPackageAllowed("pkg1")).isTrue();
        assertThat(nlf.isPackageAllowed(new VersionedPackage("any", 0))).isTrue();
    }


    @Test
    public void testConstructor() {
        ArraySet<String> pkgs = new ArraySet<>(new String[] {"pkg1", "pkg2"});
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        VersionedPackage a2= new VersionedPackage("pkg2", 2142534);
        ArraySet<VersionedPackage> pkgs = new ArraySet<>(new VersionedPackage[] {a1, a2});
        NotificationListenerFilter nlf =
                new NotificationListenerFilter(FLAG_FILTER_TYPE_ALERTING, pkgs);
        assertThat(nlf.isTypeAllowed(FLAG_FILTER_TYPE_CONVERSATIONS)).isFalse();
@@ -62,20 +65,21 @@ public class NotificationListenerFilterTest {
        assertThat(nlf.isTypeAllowed(FLAG_FILTER_TYPE_SILENT)).isFalse();
        assertThat(nlf.getTypes()).isEqualTo(FLAG_FILTER_TYPE_ALERTING);

        assertThat(nlf.getDisallowedPackages()).contains("pkg1");
        assertThat(nlf.getDisallowedPackages()).contains("pkg2");
        assertThat(nlf.isPackageAllowed("pkg1")).isFalse();
        assertThat(nlf.isPackageAllowed("pkg2")).isFalse();
        assertThat(nlf.getDisallowedPackages()).contains(a1);
        assertThat(nlf.getDisallowedPackages()).contains(a2);
        assertThat(nlf.isPackageAllowed(a1)).isFalse();
        assertThat(nlf.isPackageAllowed(a2)).isFalse();
    }

    @Test
    public void testSetDisallowedPackages() {
        NotificationListenerFilter nlf = new NotificationListenerFilter();

        ArraySet<String> pkgs = new ArraySet<>(new String[] {"pkg1"});
        ArraySet<VersionedPackage> pkgs = new ArraySet<>(
                new VersionedPackage[] {new VersionedPackage("pkg1", 0)});
        nlf.setDisallowedPackages(pkgs);

        assertThat(nlf.isPackageAllowed("pkg1")).isFalse();
        assertThat(nlf.isPackageAllowed(new VersionedPackage("pkg1", 0))).isFalse();
    }

    @Test
@@ -94,7 +98,9 @@ public class NotificationListenerFilterTest {
    @Test
    public void testDescribeContents() {
        final int expected = 0;
        ArraySet<String> pkgs = new ArraySet<>(new String[] {"pkg1", "pkg2"});
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        VersionedPackage a2= new VersionedPackage("pkg2", 2142534);
        ArraySet<VersionedPackage> pkgs = new ArraySet<>(new VersionedPackage[] {a1, a2});
        NotificationListenerFilter nlf =
                new NotificationListenerFilter(FLAG_FILTER_TYPE_ALERTING, pkgs);
        assertThat(nlf.describeContents()).isEqualTo(expected);
@@ -102,7 +108,9 @@ public class NotificationListenerFilterTest {

    @Test
    public void testParceling() {
        ArraySet<String> pkgs = new ArraySet<>(new String[] {"pkg1", "pkg2"});
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        VersionedPackage a2= new VersionedPackage("pkg2", 2142534);
        ArraySet<VersionedPackage> pkgs = new ArraySet<>(new VersionedPackage[] {a1, a2});
        NotificationListenerFilter nlf =
                new NotificationListenerFilter(FLAG_FILTER_TYPE_ALERTING, pkgs);

@@ -116,9 +124,9 @@ public class NotificationListenerFilterTest {
        assertThat(nlf1.isTypeAllowed(FLAG_FILTER_TYPE_SILENT)).isFalse();
        assertThat(nlf1.getTypes()).isEqualTo(FLAG_FILTER_TYPE_ALERTING);

        assertThat(nlf1.getDisallowedPackages()).contains("pkg1");
        assertThat(nlf1.getDisallowedPackages()).contains("pkg2");
        assertThat(nlf1.isPackageAllowed("pkg1")).isFalse();
        assertThat(nlf1.isPackageAllowed("pkg2")).isFalse();
        assertThat(nlf1.getDisallowedPackages()).contains(a1);
        assertThat(nlf1.getDisallowedPackages()).contains(a2);
        assertThat(nlf1.isPackageAllowed(a1)).isFalse();
        assertThat(nlf1.isPackageAllowed(a2)).isFalse();
    }
}
+31 −10
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ import android.content.pm.ServiceInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioAttributes;
@@ -8969,7 +8970,8 @@ public class NotificationManagerService extends SystemService {
        NotificationListenerFilter nls = mListeners.getNotificationListenerFilter(listener.mKey);
        if (nls != null
                && (!nls.isTypeAllowed(notificationType)
                || !nls.isPackageAllowed(sbn.getPackageName()))) {
                || !nls.isPackageAllowed(
                        new VersionedPackage(sbn.getPackageName(), sbn.getUid())))) {
            return false;
        }
        return true;
@@ -9580,7 +9582,8 @@ public class NotificationManagerService extends SystemService {
        static final String TAG_REQUESTED_LISTENER = "listener";
        static final String ATT_COMPONENT = "component";
        static final String ATT_TYPES = "types";
        static final String ATT_PKGS = "pkgs";
        static final String ATT_PKG = "pkg";
        static final String ATT_UID = "uid";
        static final String TAG_APPROVED = "allowed";
        static final String TAG_DISALLOWED= "disallowed";
        static final String XML_SEPARATOR = ",";
@@ -9738,6 +9741,18 @@ public class NotificationManagerService extends SystemService {
                    }
                }
            }

            // clean up anything in the disallowed pkgs list
            for (int i = 0; i < pkgList.length; i++) {
                String pkg = pkgList[i];
                int userId = UserHandle.getUserId(uidList[i]);
                for (int j = mRequestedNotificationListeners.size() - 1; j >= 0; j--) {
                    NotificationListenerFilter nlf = mRequestedNotificationListeners.valueAt(j);

                    VersionedPackage ai = new VersionedPackage(pkg, uidList[i]);
                    nlf.removePackage(ai);
                }
            }
        }

        @Override
@@ -9767,15 +9782,17 @@ public class NotificationManagerService extends SystemService {
                    int approved = FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ALERTING
                            | FLAG_FILTER_TYPE_SILENT | FLAG_FILTER_TYPE_ONGOING;

                    ArraySet<String> disallowedPkgs = new ArraySet<>();
                    ArraySet<VersionedPackage> disallowedPkgs = new ArraySet<>();
                    final int listenerOuterDepth = parser.getDepth();
                    while (XmlUtils.nextElementWithin(parser, listenerOuterDepth)) {
                        if (TAG_APPROVED.equals(parser.getName())) {
                            approved = XmlUtils.readIntAttribute(parser, ATT_TYPES);
                        } else if (TAG_DISALLOWED.equals(parser.getName())) {
                            String pkgs = XmlUtils.readStringAttribute(parser, ATT_PKGS);
                            if (!TextUtils.isEmpty(pkgs)) {
                                disallowedPkgs = new ArraySet<>(pkgs.split(XML_SEPARATOR));
                            String pkg = XmlUtils.readStringAttribute(parser, ATT_PKG);
                            int uid = XmlUtils.readIntAttribute(parser, ATT_UID);
                            if (!TextUtils.isEmpty(pkg)) {
                                VersionedPackage ai = new VersionedPackage(pkg, uid);
                                disallowedPkgs.add(ai);
                            }
                        }
                    }
@@ -9800,10 +9817,14 @@ public class NotificationManagerService extends SystemService {
                XmlUtils.writeIntAttribute(out, ATT_TYPES, nlf.getTypes());
                out.endTag(null, TAG_APPROVED);

                for (VersionedPackage ai : nlf.getDisallowedPackages()) {
                    if (!TextUtils.isEmpty(ai.getPackageName())) {
                        out.startTag(null, TAG_DISALLOWED);
                XmlUtils.writeStringAttribute(
                        out, ATT_PKGS, String.join(XML_SEPARATOR, nlf.getDisallowedPackages()));
                        XmlUtils.writeStringAttribute(out, ATT_PKG, ai.getPackageName());
                        XmlUtils.writeIntAttribute(out, ATT_UID, ai.getVersionCode());
                        out.endTag(null, TAG_DISALLOWED);
                    }
                }

                out.endTag(null, TAG_REQUESTED_LISTENER);
            }
+32 −9
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.when;

import android.app.INotificationManager;
import android.content.ComponentName;
import android.content.pm.VersionedPackage;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -83,11 +84,10 @@ public class NotificationListenersTest extends UiServiceTestCase {
        String xml = "<req_listeners>"
                + "<listener component=\"" + mCn1.flattenToString() + "\" user=\"0\">"
                + "<allowed types=\"7\" />"
                + "<disallowed pkgs=\"\" />"
                + "</listener>"
                + "<listener component=\"" + mCn2.flattenToString() + "\" user=\"10\">"
                + "<allowed types=\"4\" />"
                + "<disallowed pkgs=\"something\" />"
                + "<disallowed pkg=\"pkg1\" uid=\"243\"/>"
                + "</listener>"
                + "</req_listeners>";

@@ -103,8 +103,9 @@ public class NotificationListenersTest extends UiServiceTestCase {
    @Test
    public void testWriteExtraTag() throws Exception {
        NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        NotificationListenerFilter nlf2 =
                new NotificationListenerFilter(4, new ArraySet<>(new String[] {"something"}));
                new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
        mListeners.setNotificationListenerFilter(Pair.create(mCn1, 0), nlf);
        mListeners.setNotificationListenerFilter(Pair.create(mCn2, 10), nlf2);

@@ -134,16 +135,18 @@ public class NotificationListenersTest extends UiServiceTestCase {

        assertThat(mListeners.getNotificationListenerFilter(Pair.create(mCn2, 10)).getTypes())
                .isEqualTo(4);
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        assertThat(mListeners.getNotificationListenerFilter(Pair.create(mCn2, 10))
                .getDisallowedPackages())
                .contains("something");
                .contains(a1);
    }

    @Test
    public void testOnUserRemoved() {
        NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        NotificationListenerFilter nlf2 =
                new NotificationListenerFilter(4, new ArraySet<>(new String[] {"something"}));
                new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
        mListeners.setNotificationListenerFilter(Pair.create(mCn1, 0), nlf);
        mListeners.setNotificationListenerFilter(Pair.create(mCn2, 10), nlf2);

@@ -157,8 +160,9 @@ public class NotificationListenersTest extends UiServiceTestCase {
    @Test
    public void testOnUserUnlocked() {
        // one exists already, say from xml
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        NotificationListenerFilter nlf =
                new NotificationListenerFilter(4, new ArraySet<>(new String[] {"something"}));
                new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
        mListeners.setNotificationListenerFilter(Pair.create(mCn2, 0), nlf);

        // new service exists or backfilling on upgrade to S
@@ -188,7 +192,7 @@ public class NotificationListenersTest extends UiServiceTestCase {
                .isEqualTo(4);
        assertThat(mListeners.getNotificationListenerFilter(Pair.create(mCn2, 0))
                .getDisallowedPackages())
                .contains("something");
                .contains(a1);

        assertThat(mListeners.getNotificationListenerFilter(
                Pair.create(si.getComponentName(), 0)).getTypes())
@@ -205,8 +209,9 @@ public class NotificationListenersTest extends UiServiceTestCase {
    @Test
    public void testOnPackageChanged() {
        NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        NotificationListenerFilter nlf2 =
                new NotificationListenerFilter(4, new ArraySet<>(new String[] {"something"}));
                new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
        mListeners.setNotificationListenerFilter(Pair.create(mCn1, 0), nlf);
        mListeners.setNotificationListenerFilter(Pair.create(mCn2, 10), nlf2);

@@ -224,8 +229,9 @@ public class NotificationListenersTest extends UiServiceTestCase {
    @Test
    public void testOnPackageChanged_removing() {
        NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        NotificationListenerFilter nlf2 =
                new NotificationListenerFilter(4, new ArraySet<>(new String[] {"something"}));
                new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
        mListeners.setNotificationListenerFilter(Pair.create(mCn1, 0), nlf);
        mListeners.setNotificationListenerFilter(Pair.create(mCn2, 0), nlf2);

@@ -239,4 +245,21 @@ public class NotificationListenersTest extends UiServiceTestCase {
                .isEqualTo(4);
    }

    @Test
    public void testOnPackageChanged_removingDisallowedPackage() {
        NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());
        VersionedPackage a1 = new VersionedPackage("pkg1", 243);
        NotificationListenerFilter nlf2 =
                new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
        mListeners.setNotificationListenerFilter(Pair.create(mCn1, 0), nlf);
        mListeners.setNotificationListenerFilter(Pair.create(mCn2, 0), nlf2);

        String[] pkgs = new String[] {"pkg1"};
        int[] uids = new int[] {243};
        mListeners.onPackagesChanged(true, pkgs, uids);

        assertThat(mListeners.getNotificationListenerFilter(Pair.create(mCn1, 0))
                .getDisallowedPackages()).isEmpty();
    }

}
+2 −2
Original line number Diff line number Diff line
@@ -464,7 +464,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

        // Setup managed services
        when(mNlf.isTypeAllowed(anyInt())).thenReturn(true);
        when(mNlf.isPackageAllowed(anyString())).thenReturn(true);
        when(mNlf.isPackageAllowed(any())).thenReturn(true);
        when(mNlf.isPackageAllowed(null)).thenReturn(true);
        when(mListeners.getNotificationListenerFilter(any())).thenReturn(mNlf);
        mListener = mListeners.new ManagedServiceInfo(
@@ -7307,7 +7307,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

    @Test
    public void testIsVisibleToListener_disallowedPackage() {
        when(mNlf.isPackageAllowed(null)).thenReturn(false);
        when(mNlf.isPackageAllowed(any())).thenReturn(false);

        StatusBarNotification sbn = mock(StatusBarNotification.class);
        when(sbn.getUserId()).thenReturn(10);