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

Commit 411e2951 authored by Alexander Roederer's avatar Alexander Roederer Committed by Android (Google) Code Review
Browse files

Merge "Clear recent notifs in History on package removed" into main

parents ce2d6221 434fd329
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -828,6 +828,22 @@ public class NotificationManagerService extends SystemService {
            }
        }
        // Removes all notifications with the specified user & package.
        public void removePackageNotifications(String pkg, @UserIdInt int userId) {
            synchronized (mBufferLock) {
                Iterator<Pair<StatusBarNotification, Integer>> bufferIter = descendingIterator();
                while (bufferIter.hasNext()) {
                    final Pair<StatusBarNotification, Integer> pair = bufferIter.next();
                    if (pair.first != null
                            && userId == pair.first.getNormalizedUserId()
                            && pkg != null && pkg.equals(pair.first.getPackageName())
                            && pair.first.getNotification() != null) {
                        bufferIter.remove();
                    }
                }
            }
        }
        void dumpImpl(PrintWriter pw, @NonNull DumpFilter filter) {
            synchronized (mBufferLock) {
                Iterator<Pair<StatusBarNotification, Integer>> iter = descendingIterator();
@@ -1902,7 +1918,6 @@ public class NotificationManagerService extends SystemService {
                        unhideNotificationsForPackages(pkgList, uidList);
                    }
                }
                mHandler.scheduleOnPackageChanged(removingPackage, changeUserId, pkgList, uidList);
            }
        }
@@ -4216,7 +4231,8 @@ public class NotificationManagerService extends SystemService {
            boolean previouslyExisted = mPreferencesHelper.deleteNotificationChannel(
                    pkg, callingUid, channelId, callingUid, isSystemOrSystemUi);
            if (previouslyExisted) {
                // Remove from both recent notification archive and notification history
                // Remove from both recent notification archive (recently dismissed notifications)
                // and notification history
                mArchive.removeChannelNotifications(pkg, callingUser, channelId);
                mHistoryManager.deleteNotificationChannel(pkg, callingUid, channelId);
                mListeners.notifyNotificationChannelChanged(pkg,
@@ -9418,7 +9434,11 @@ public class NotificationManagerService extends SystemService {
            for (int i = 0; i < size; i++) {
                final String pkg = pkgList[i];
                final int uid = uidList[i];
                mHistoryManager.onPackageRemoved(UserHandle.getUserId(uid), pkg);
                final int userHandle = UserHandle.getUserId(uid);
                // Removes this package's notifications from both recent notification archive
                // (recently dismissed notifications) and notification history.
                mArchive.removePackageNotifications(pkg, userHandle);
                mHistoryManager.onPackageRemoved(userHandle, pkg);
            }
        }
        if (preferencesChanged) {
+30 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;

@@ -39,6 +40,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.server.UiServiceTestCase;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -55,6 +57,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ArchiveTest extends UiServiceTestCase {
    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private static final int SIZE = 5;

    private NotificationManagerService.Archive mArchive;
@@ -249,4 +254,29 @@ public class ArchiveTest extends UiServiceTestCase {
            assertThat(expected).contains(sbn.getKey());
        }
    }

    @Test
    public void testRemoveNotificationsByPackage() {
        List<String> expected = new ArrayList<>();

        StatusBarNotification sbn_remove = getNotification("pkg_remove", 0,
                UserHandle.of(USER_CURRENT));
        mArchive.record(sbn_remove, REASON_CANCEL);

        StatusBarNotification sbn_keep = getNotification("pkg_keep", 1,
                UserHandle.of(USER_CURRENT));
        mArchive.record(sbn_keep, REASON_CANCEL);
        expected.add(sbn_keep.getKey());

        StatusBarNotification sbn_remove2 = getNotification("pkg_remove", 2,
                UserHandle.of(USER_CURRENT));
        mArchive.record(sbn_remove2, REASON_CANCEL);

        mArchive.removePackageNotifications("pkg_remove", USER_CURRENT);
        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
        assertThat(actual).hasSize(expected.size());
        for (StatusBarNotification sbn : actual) {
            assertThat(expected).contains(sbn.getKey());
        }
    }
}
+68 −2
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.O_MR1;
import static android.os.Build.VERSION_CODES.P;
import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
@@ -72,7 +73,6 @@ import static android.os.UserHandle.USER_SYSTEM;
import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
@@ -307,7 +307,6 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service.
@@ -813,6 +812,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mPackageIntentReceiver.onReceive(getContext(), intent);
    }
    private void simulatePackageRemovedBroadcast(String pkg, int uid) {
        // mimics receive broadcast that package is removed, but doesn't remove the package.
        final Bundle extras = new Bundle();
        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
                new String[]{pkg});
        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, new int[]{uid});
        final Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
        intent.setData(Uri.parse("package:" + pkg));
        intent.putExtras(extras);
        mPackageIntentReceiver.onReceive(getContext(), intent);
    }
    private void simulatePackageDistractionBroadcast(int flag, String[] pkgs, int[] uids) {
        // mimics receive broadcast that package is (un)distracting
        // but does not actually register that info with packagemanager
@@ -878,6 +891,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mTestNotificationChannel.setAllowBubbles(channelEnabled);
    }
    private void setUpPrefsForHistory(int uid, boolean globalEnabled) {
        // Sets NOTIFICATION_HISTORY_ENABLED setting for calling process uid
        Settings.Secure.putIntForUser(mContext.getContentResolver(),
                Settings.Secure.NOTIFICATION_HISTORY_ENABLED, globalEnabled ? 1 : 0, uid);
        // Sets NOTIFICATION_HISTORY_ENABLED setting for uid 0
        Settings.Secure.putInt(mContext.getContentResolver(),
                Settings.Secure.NOTIFICATION_HISTORY_ENABLED, globalEnabled ? 1 : 0);
        // Forces an update by calling observe on mSettingsObserver, which picks up the settings
        // changes above.
        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START, mMainLooper);
        assertEquals(globalEnabled, Settings.Secure.getIntForUser(mContext.getContentResolver(),
                Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0 /* =def */, uid) != 0);
    }
    private StatusBarNotification generateSbn(String pkg, int uid, long postTime, int userId) {
        Notification.Builder nb = new Notification.Builder(mContext, "a")
                .setContentTitle("foo")
@@ -9830,6 +9859,43 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        verify(mHistoryManager, times(1)).onPackageRemoved(UserHandle.getUserId(uids[1]), pkgs[1]);
    }
    @Test
    public void testHandleOnPackageRemoved_ClearsHistory() throws RemoteException {
        // Enables Notification History setting
        setUpPrefsForHistory(mUid, true /* =enabled */);
        // Posts a notification to the mTestNotificationChannel.
        final NotificationRecord notif = generateNotificationRecord(
                mTestNotificationChannel, 1, null, false);
        mService.addNotification(notif);
        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(
                notif.getSbn().getPackageName());
        assertEquals(1, notifs.length);
        // Cancels all notifications.
        mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0,
                notif.getUserId(), REASON_CANCEL);
        waitForIdle();
        notifs = mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
        assertEquals(0, notifs.length);
        // Checks that notification history's recently canceled archive contains the notification.
        notifs = mBinderService.getHistoricalNotificationsWithAttribution(PKG,
                        mContext.getAttributionTag(), 5 /* count */, false /* includeSnoozed */);
        waitForIdle();
        assertEquals(1, notifs.length);
        // Remove sthe package that contained the channel
        simulatePackageRemovedBroadcast(PKG, mUid);
        waitForIdle();
        // Checks that notification history no longer contains the notification.
        notifs = mBinderService.getHistoricalNotificationsWithAttribution(
                PKG, mContext.getAttributionTag(), 5 /* count */, false /* includeSnoozed */);
        waitForIdle();
        assertEquals(0, notifs.length);
    }
    @Test
    public void testNotificationHistory_addNoisyNotification() throws Exception {
        NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,