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

Commit ec7cea11 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Expire old bitmaps as owning app

It's possible for an old notification to have been posted by a
now-revoked notification delegate. we should still expire
bitmaps in this case

Test: manual: modify CTS testNotificationDelegate_grantAndRevoke to
grant / post / revoke / wait and set NMS to constantly expire - ensure
no crash and notification updated properly in the shade
Test: NotificationManagerServiceTest
Fixes: 374295673
Flag: EXEMPT bugfix

Change-Id: Ieeea79d4e78b072a68551dcc9e34c493faca9373
parent d9b1b338
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BA
import static android.app.NotificationManager.zenModeFromInterruptionFilter;
import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
import static android.app.backup.NotificationLoggingConstants.ERROR_XML_PARSING;
import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
@@ -161,8 +163,6 @@ import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
import static android.app.backup.NotificationLoggingConstants.ERROR_XML_PARSING;
import static com.android.server.notification.Flags.expireBitmaps;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_ANIM_BUFFER;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
@@ -7742,10 +7742,11 @@ public class NotificationManagerService extends SystemService {
        // Make Notification silent
        r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
        // Repost
        // Repost as the original app (even if it was posted by a delegate originally
        // because the delegate may now be revoked)
        enqueueNotificationInternal(r.getSbn().getPackageName(),
                r.getSbn().getOpPkg(), r.getSbn().getUid(),
                r.getSbn().getInitialPid(), r.getSbn().getTag(),
                r.getSbn().getPackageName(), r.getSbn().getUid(),
                MY_PID, r.getSbn().getTag(),
                r.getSbn().getId(), r.getNotification(),
                r.getSbn().getUserId(), /* postSilently= */ true,
                /* byForegroundService= */ false,
@@ -7984,7 +7985,6 @@ public class NotificationManagerService extends SystemService {
        r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg));
        boolean isImportanceFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
        r.setImportanceFixed(isImportanceFixed);
        if (notification.isFgsOrUij()) {
            if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
                        || !channel.isUserVisibleTaskShown())
+42 −10
Original line number Diff line number Diff line
@@ -43,8 +43,8 @@ import static android.app.Notification.FLAG_PROMOTED_ONGOING;
import static android.app.Notification.FLAG_USER_INITIATED_JOB;
import static android.app.Notification.GROUP_ALERT_CHILDREN;
import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.PROMOTIONS_ID;
import static android.app.NotificationChannel.RECS_ID;
import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
@@ -78,7 +78,6 @@ import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_RULES;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_WATCH;
@@ -334,12 +333,12 @@ import com.android.server.utils.quota.MultiRateLimiter;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -364,7 +363,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -14119,9 +14117,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
    }
    private NotificationRecord createBigPictureRecord(boolean isBigPictureStyle, boolean hasImage,
                                                      boolean isImageBitmap, boolean isExpired) {
        Notification.Builder builder = new Notification.Builder(mContext);
    private Notification createBigPictureNotification(boolean isBigPictureStyle, boolean hasImage,
            boolean isImageBitmap) {
        Notification.Builder builder = new Notification.Builder(mContext)
                .setSmallIcon(android.R.drawable.sym_def_app_icon);
        Notification.BigPictureStyle style = new Notification.BigPictureStyle();
        if (isBigPictureStyle && hasImage) {
@@ -14137,12 +14136,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        Notification notification = builder.setChannelId(TEST_CHANNEL_ID).build();
        return notification;
    }
    private NotificationRecord createBigPictureRecord(boolean isBigPictureStyle, boolean hasImage,
            boolean isImageBitmap, boolean isExpired) {
        long timePostedMs = System.currentTimeMillis();
        if (isExpired) {
            timePostedMs -= BITMAP_DURATION.toMillis();
        }
        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                notification, UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
                createBigPictureNotification(isBigPictureStyle, hasImage, isImageBitmap),
                UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
        return new NotificationRecord(mContext, sbn, mTestNotificationChannel);
    }
@@ -14153,6 +14158,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        waitForIdle();
    }
    @Test
    public void testRemoveBitmaps_canRemoveRevokedDelegate() throws Exception {
        Notification n = createBigPictureNotification(true, true, true);
        long timePostedMs = System.currentTimeMillis();
        timePostedMs -= BITMAP_DURATION.toMillis();
        when(mPermissionHelper.hasPermission(UID_O)).thenReturn(true);
        when(mPackageManagerInternal.isSameApp(PKG_O, UID_O, UserHandle.getUserId(UID_O)))
                .thenReturn(true);
        mService.mPreferencesHelper.createNotificationChannel(PKG_O, UID_O,
                mTestNotificationChannel, true /* fromTargetApp */, false, UID_O,
                false);
        mBinderService.createNotificationChannels(PKG_O, new ParceledListSlice(
                Arrays.asList(mTestNotificationChannel, mSilentChannel, mMinChannel)));
        StatusBarNotification sbn = new StatusBarNotification(PKG_O, "old.delegate", 8, "tag",
                UID_O, 0, n, UserHandle.getUserHandleForUid(UID_O), null, timePostedMs);
        mService.addNotification(new NotificationRecord(mContext, sbn, mTestNotificationChannel));
        mInternalService.removeBitmaps();
        waitForIdle();
        verify(mWorkerHandler, times(1))
                .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
    }
    @Test
    public void testRemoveBitmaps_notBigPicture_noRepost() {
        addRecordAndRemoveBitmaps(