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

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

Merge "Allow media notifications to always be posted"

parents 9371fa74 3c745416
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -6784,11 +6784,13 @@ public class NotificationManagerService extends SystemService {


        // blocked apps
        boolean isMediaNotification = n.isMediaNotification()
                && n.extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) != null;
        boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid);
        synchronized (mNotificationLock) {
            isBlocked |= isRecordBlockedLocked(r);
        }
        if (isBlocked) {
        if (isBlocked && !isMediaNotification) {
            if (DBG) {
                Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
                        + " by user request.");
@@ -7174,7 +7176,13 @@ public class NotificationManagerService extends SystemService {
                        return;
                    }

                    if (appBanned || isRecordBlockedLocked(r)) {
                    final StatusBarNotification n = r.getSbn();
                    final Notification notification = n.getNotification();

                    boolean isMediaNotification = notification.isMediaNotification()
                            && notification.extras.getParcelable(
                                    Notification.EXTRA_MEDIA_SESSION) != null;
                    if (!isMediaNotification && (appBanned || isRecordBlockedLocked(r))) {
                        mUsageStats.registerBlocked(r);
                        if (DBG) {
                            Slog.e(TAG, "Suppressing notification from package " + pkg);
@@ -7189,8 +7197,6 @@ public class NotificationManagerService extends SystemService {
                        mUsageStats.registerSuspendedByAdmin(r);
                    }
                    NotificationRecord old = mNotificationsByKey.get(key);
                    final StatusBarNotification n = r.getSbn();
                    final Notification notification = n.getNotification();

                    // Make sure the SBN has an instance ID for statsd logging.
                    if (old == null || old.getSbn().getInstanceId() == null) {
+42 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.media.AudioManager;
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -8465,4 +8466,45 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            fail("call to matchesCallFilter with listener permissions should work");
        }
    }

    @Test
    public void testMediaNotificationsBypassBlock() throws Exception {
        when(mAmi.getPendingIntentFlags(any(IIntentSender.class)))
                .thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT);
        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);

        Notification.Builder nb = new Notification.Builder(
                mContext, mTestNotificationChannel.getId())
                .setContentTitle("foo")
                .setSmallIcon(android.R.drawable.sym_def_app_icon)
                .addAction(new Notification.Action.Builder(null, "test", null).build());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        mBinderService.setNotificationsEnabledForPackage(
                r.getSbn().getPackageName(), r.getUid(), false);

        // normal blocked notifications - blocked
        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();

        // just using the style - blocked
        nb.setStyle(new Notification.MediaStyle());
        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();

        // style + media session - bypasses block
        nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
    }
}
+101 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.app.PendingIntent.FLAG_MUTABLE;
import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.UserHandle.USER_SYSTEM;
@@ -84,6 +86,7 @@ import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.session.MediaSession;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
@@ -711,4 +714,102 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase {

        assertThat(r.isImportanceFixed()).isTrue();
    }

    @Test
    public void testMediaNotificationsBypassBlock() throws Exception {
        when(mAmi.getPendingIntentFlags(any(IIntentSender.class)))
                .thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT);
        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);

        Notification.Builder nb = new Notification.Builder(
                mContext, mTestNotificationChannel.getId())
                .setContentTitle("foo")
                .setSmallIcon(android.R.drawable.sym_def_app_icon)
                .addAction(new Notification.Action.Builder(null, "test", null).build());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);

        // normal blocked notifications - blocked
        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();

        // just using the style - blocked
        nb.setStyle(new Notification.MediaStyle());
        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();

        // style + media session - bypasses block
        nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
    }

    @Test
    public void testMediaNotificationsBypassBlock_atPost() throws Exception {
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);

        Notification.Builder nb = new Notification.Builder(
                mContext, mTestNotificationChannel.getId())
                .setContentTitle("foo")
                .setSmallIcon(android.R.drawable.sym_def_app_icon)
                .addAction(new Notification.Action.Builder(null, "test", null).build());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);

        mService.addEnqueuedNotification(r);
        NotificationManagerService.PostNotificationRunnable runnable =
                mService.new PostNotificationRunnable(r.getKey());
        runnable.run();
        waitForIdle();

        verify(mUsageStats).registerBlocked(any());
        verify(mUsageStats, never()).registerPostedByApp(any());

        // just using the style - blocked
        mService.clearNotifications();
        reset(mUsageStats);
        nb.setStyle(new Notification.MediaStyle());
        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        mService.addEnqueuedNotification(r);
        runnable = mService.new PostNotificationRunnable(r.getKey());
        runnable.run();
        waitForIdle();

        verify(mUsageStats).registerBlocked(any());
        verify(mUsageStats, never()).registerPostedByApp(any());

        // style + media session - bypasses block
        mService.clearNotifications();
        reset(mUsageStats);
        nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        mService.addEnqueuedNotification(r);
        runnable = mService.new PostNotificationRunnable(r.getKey());
        runnable.run();
        waitForIdle();

        verify(mUsageStats, never()).registerBlocked(any());
        verify(mUsageStats).registerPostedByApp(any());
    }
}