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

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

Add ability to delete individual history items

Test: atest
Bug: 137396965
Change-Id: I825a93bdf8fd28c4d58bf3df4a00c7c6505678bf
parent a404c12d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ interface INotificationManager
    int getAppsBypassingDndCount(int uid);
    ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId);
    boolean isPackagePaused(String pkg);
    void deleteNotificationHistoryItem(String pkg, int uid, long postedTime);

    void silenceNotificationSound();

+20 −0
Original line number Diff line number Diff line
@@ -345,6 +345,26 @@ public final class NotificationHistory implements Parcelable {
        poolStringsFromNotifications();
    }

    /**
     * Removes an individual historical notification and regenerates the string pool
     */
    public boolean removeNotificationFromWrite(String packageName, long postedTime) {
        boolean removed = false;
        for (int i = mNotificationsToWrite.size() - 1; i >= 0; i--) {
            HistoricalNotification hn = mNotificationsToWrite.get(i);
            if (packageName.equals(hn.getPackage())
                    && postedTime == hn.getPostedTimeMs()) {
                removed = true;
                mNotificationsToWrite.remove(i);
            }
        }
        if (removed) {
            poolStringsFromNotifications();
        }

        return removed;
    }

    /**
     * Gets pooled strings in order to write them to disk
     */
+34 −0
Original line number Diff line number Diff line
@@ -233,6 +233,40 @@ public class NotificationHistoryTest {
                .containsExactlyElementsIn(postRemoveExpectedEntries);
    }

    @Test
    public void testRemoveNotificationFromWrite() {
        NotificationHistory history = new NotificationHistory();

        List<HistoricalNotification> postRemoveExpectedEntries = new ArrayList<>();
        List<String> postRemoveExpectedStrings = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            HistoricalNotification n = getHistoricalNotification("pkg", i);

            if (987654323 != n.getPostedTimeMs()) {
                postRemoveExpectedStrings.add(n.getPackage());
                postRemoveExpectedStrings.add(n.getChannelName());
                postRemoveExpectedStrings.add(n.getChannelId());
                postRemoveExpectedEntries.add(n);
            }

            history.addNotificationToWrite(n);
        }

        history.poolStringsFromNotifications();

        assertThat(history.getNotificationsToWrite().size()).isEqualTo(10);
        // 1 package name and 10 unique channel names and ids
        assertThat(history.getPooledStringsToWrite().length).isEqualTo(21);

        history.removeNotificationFromWrite("pkg", 987654323);


        // 1 package names and 9 * 2 unique channel names and ids
        assertThat(history.getPooledStringsToWrite().length).isEqualTo(19);
        assertThat(history.getNotificationsToWrite())
                .containsExactlyElementsIn(postRemoveExpectedEntries);
    }

    @Test
    public void testParceling() {
        NotificationHistory history = new NotificationHistory();
+48 −0
Original line number Diff line number Diff line
@@ -170,6 +170,11 @@ public class NotificationHistoryDatabase {
        mFileWriteHandler.post(rpr);
    }

    public void deleteNotificationHistoryItem(String pkg, long postedTime) {
        RemoveNotificationRunnable rnr = new RemoveNotificationRunnable(pkg, postedTime);
        mFileWriteHandler.post(rnr);
    }

    public void addNotification(final HistoricalNotification notification) {
        synchronized (mLock) {
            mBuffer.addNewNotificationToWrite(notification);
@@ -367,6 +372,49 @@ public class NotificationHistoryDatabase {
        }
    }

    final class RemoveNotificationRunnable implements Runnable {
        private String mPkg;
        private long mPostedTime;
        private NotificationHistory mNotificationHistory;

        public RemoveNotificationRunnable(String pkg, long postedTime) {
            mPkg = pkg;
            mPostedTime = postedTime;
        }

        @VisibleForTesting
        void setNotificationHistory(NotificationHistory nh) {
            mNotificationHistory = nh;
        }

        @Override
        public void run() {
            if (DEBUG) Slog.d(TAG, "RemovePackageRunnable");
            synchronized (mLock) {
                // Remove from pending history
                mBuffer.removeNotificationFromWrite(mPkg, mPostedTime);

                Iterator<AtomicFile> historyFileItr = mHistoryFiles.iterator();
                while (historyFileItr.hasNext()) {
                    final AtomicFile af = historyFileItr.next();
                    try {
                        NotificationHistory notificationHistory = mNotificationHistory != null
                                ? mNotificationHistory
                                : new NotificationHistory();
                        readLocked(af, notificationHistory,
                                new NotificationHistoryFilter.Builder().build());
                        if(notificationHistory.removeNotificationFromWrite(mPkg, mPostedTime)) {
                            writeLocked(af, notificationHistory);
                        }
                    } catch (Exception e) {
                        Slog.e(TAG, "Cannot clean up file on notification removal "
                                + af.getBaseFile().getName(), e);
                    }
                }
            }
        }
    }

    public static final class NotificationHistoryFileAttrProvider implements
            NotificationHistoryDatabase.FileAttrProvider {
        final static String TAG = "NotifHistoryFileDate";
+17 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ public class NotificationHistoryManager {
        }
    }

    public void onPackageRemoved(int userId, String packageName) {
    public void onPackageRemoved(@UserIdInt int userId, String packageName) {
        synchronized (mLock) {
            if (!mUserUnlockedStates.get(userId, false)) {
                if (mHistoryEnabled.get(userId, false)) {
@@ -150,6 +150,22 @@ public class NotificationHistoryManager {
        }
    }

    public void deleteNotificationHistoryItem(String pkg, int uid, long postedTime) {
        synchronized (mLock) {
            int userId = UserHandle.getUserId(uid);
            final NotificationHistoryDatabase userHistory =
                    getUserHistoryAndInitializeIfNeededLocked(userId);
            // TODO: it shouldn't be possible to delete a notification entry while the user is
            // locked but we should handle it
            if (userHistory == null) {
                Slog.w(TAG, "Attempted to remove notif for locked/gone/disabled user "
                        + userId);
                return;
            }
            userHistory.deleteNotificationHistoryItem(pkg, postedTime);
        }
    }

    // TODO: wire this up to AMS when power button is long pressed
    public void triggerWriteToDisk() {
        synchronized (mLock) {
Loading