From e43fac3f26c9cff958787d86ae6ae9d831818369 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 20 Nov 2019 13:36:24 -0500 Subject: [PATCH] Add Settings flag to turn notif history on/off Test: atest Bug: 137396965 Change-Id: I63af12171c792305a16c6d72e809bf8f15cd215c --- core/java/android/provider/Settings.java | 9 + .../settings/backup/SecureSettings.java | 1 + .../validators/SecureSettingsValidators.java | 1 + .../NotificationHistoryDatabase.java | 8 + .../NotificationHistoryManager.java | 108 ++++++++++- .../NotificationHistoryManagerTest.java | 172 +++++++++++++++--- 6 files changed, 262 insertions(+), 37 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 0af2c36108dfa..758ff5315b37b 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8155,6 +8155,15 @@ public final class Settings { @TestApi public static final String NOTIFICATION_BADGING = "notification_badging"; + /** + * When enabled the system will maintain a rolling history of received notifications. When + * disabled the history will be disabled and deleted. + * + * The value 1 - enable, 0 - disable + * @hide + */ + public static final String NOTIFICATION_HISTORY_ENABLED = "notification_history_enabled"; + /** * Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right * swipe). diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 146f30d788d3c..3b929b901e498 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -126,6 +126,7 @@ public class SecureSettings { Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, Settings.Secure.SHOW_NOTIFICATION_SNOOZE, + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, Settings.Secure.ZEN_DURATION, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 0c3254a5ed029..9460d27f7843c 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -182,6 +182,7 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.SHOW_NOTIFICATION_SNOOZE, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.NOTIFICATION_HISTORY_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ZEN_DURATION, ANY_INTEGER_VALIDATOR); VALIDATORS.put(Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.SHOW_ZEN_SETTINGS_SUGGESTION, BOOLEAN_VALIDATOR); diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java index 378ca4a51974d..4ec79e1377604 100644 --- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java +++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java @@ -223,6 +223,13 @@ public class NotificationHistoryDatabase { } } + public void disableHistory() { + synchronized (mLock) { + mHistoryDir.delete(); + mHistoryFiles.clear(); + } + } + /** * Remove any files that are too old and schedule jobs to clean up the rest */ @@ -241,6 +248,7 @@ public class NotificationHistoryDatabase { Slog.d(TAG, "Removed " + currentOldestFile.getBaseFile().getName()); } currentOldestFile.delete(); + // TODO: delete all relevant bitmaps, once they exist mHistoryFiles.removeLast(); } else { // all remaining files are newer than the cut off; schedule jobs to delete diff --git a/services/core/java/com/android/server/notification/NotificationHistoryManager.java b/services/core/java/com/android/server/notification/NotificationHistoryManager.java index a350a6b2acd58..2e7016b561b60 100644 --- a/services/core/java/com/android/server/notification/NotificationHistoryManager.java +++ b/services/core/java/com/android/server/notification/NotificationHistoryManager.java @@ -21,9 +21,16 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.NotificationHistory; import android.app.NotificationHistory.HistoricalNotification; +import android.content.ContentResolver; import android.content.Context; +import android.content.pm.UserInfo; +import android.database.ContentObserver; +import android.net.Uri; import android.os.Environment; +import android.os.Handler; +import android.os.UserHandle; import android.os.UserManager; +import android.provider.Settings; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; @@ -49,6 +56,8 @@ public class NotificationHistoryManager { private final Context mContext; private final UserManager mUserManager; + @VisibleForTesting + final SettingsObserver mSettingsObserver; private final Object mLock = new Object(); @GuardedBy("mLock") private final SparseArray mUserState = new SparseArray<>(); @@ -57,19 +66,26 @@ public class NotificationHistoryManager { // TODO: does this need to be persisted across reboots? @GuardedBy("mLock") private final SparseArray> mUserPendingPackageRemovals = new SparseArray<>(); + @GuardedBy("mLock") + private final SparseBooleanArray mHistoryEnabled = new SparseBooleanArray(); - public NotificationHistoryManager(Context context) { + public NotificationHistoryManager(Context context, Handler handler) { mContext = context; mUserManager = context.getSystemService(UserManager.class); + mSettingsObserver = new SettingsObserver(handler); } - public void onUserUnlocked(@UserIdInt int userId) { + void onBootPhaseAppsCanStart() { + mSettingsObserver.observe(); + } + + void onUserUnlocked(@UserIdInt int userId) { synchronized (mLock) { mUserUnlockedStates.put(userId, true); final NotificationHistoryDatabase userHistory = getUserHistoryAndInitializeIfNeededLocked(userId); if (userHistory == null) { - Slog.i(TAG, "Attempted to unlock stopped or removed user " + userId); + Slog.i(TAG, "Attempted to unlock gone/disabled user " + userId); return; } @@ -81,6 +97,11 @@ public class NotificationHistoryManager { } mUserPendingPackageRemovals.put(userId, null); } + + // delete history if it was disabled when the user was locked + if (!mHistoryEnabled.get(userId)) { + userHistory.disableHistory(); + } } } @@ -96,6 +117,7 @@ public class NotificationHistoryManager { // Actual data deletion is handled by other parts of the system (the entire directory is // removed) - we just need clean up our internal state for GC mUserPendingPackageRemovals.put(userId, null); + mHistoryEnabled.put(userId, false); onUserStopped(userId); } } @@ -103,10 +125,12 @@ public class NotificationHistoryManager { void onPackageRemoved(int userId, String packageName) { synchronized (mLock) { if (!mUserUnlockedStates.get(userId, false)) { - List userPendingRemovals = - mUserPendingPackageRemovals.get(userId, new ArrayList<>()); - userPendingRemovals.add(packageName); - mUserPendingPackageRemovals.put(userId, userPendingRemovals); + if (mHistoryEnabled.get(userId, false)) { + List userPendingRemovals = + mUserPendingPackageRemovals.get(userId, new ArrayList<>()); + userPendingRemovals.add(packageName); + mUserPendingPackageRemovals.put(userId, userPendingRemovals); + } return; } final NotificationHistoryDatabase userHistory = mUserState.get(userId); @@ -139,7 +163,7 @@ public class NotificationHistoryManager { final NotificationHistoryDatabase userHistory = getUserHistoryAndInitializeIfNeededLocked(notification.getUserId()); if (userHistory == null) { - Slog.w(TAG, "Attempted to add notif for locked/gone user " + Slog.w(TAG, "Attempted to add notif for locked/gone/disabled user " + notification.getUserId()); return; } @@ -157,7 +181,7 @@ public class NotificationHistoryManager { final NotificationHistoryDatabase userHistory = getUserHistoryAndInitializeIfNeededLocked(userId); if (userHistory == null) { - Slog.i(TAG, "Attempted to read history for locked/gone user " +userId); + Slog.i(TAG, "Attempted to read history for locked/gone/disabled user " +userId); continue; } mergedHistory.addNotificationsToWrite(userHistory.readNotificationHistory()); @@ -172,7 +196,7 @@ public class NotificationHistoryManager { final NotificationHistoryDatabase userHistory = getUserHistoryAndInitializeIfNeededLocked(userId); if (userHistory == null) { - Slog.i(TAG, "Attempted to read history for locked/gone user " +userId); + Slog.i(TAG, "Attempted to read history for locked/gone/disabled user " +userId); return new android.app.NotificationHistory(); } @@ -180,9 +204,38 @@ public class NotificationHistoryManager { } } + public boolean isHistoryEnabled(@UserIdInt int userId) { + synchronized (mLock) { + return mHistoryEnabled.get(userId); + } + } + + void onHistoryEnabledChanged(@UserIdInt int userId, boolean historyEnabled) { + synchronized (mLock) { + mHistoryEnabled.put(userId, historyEnabled); + + // These requests might fail if the user is locked; onUserUnlocked will pick up those + // cases + final NotificationHistoryDatabase userHistory = + getUserHistoryAndInitializeIfNeededLocked(userId); + if (userHistory != null) { + if (!historyEnabled) { + userHistory.disableHistory(); + } + } + } + } + @GuardedBy("mLock") private @Nullable NotificationHistoryDatabase getUserHistoryAndInitializeIfNeededLocked( int userId) { + if (!mHistoryEnabled.get(userId)) { + if (DEBUG) { + Slog.i(TAG, "History disabled for user " + userId); + } + mUserState.put(userId, null); + return null; + } NotificationHistoryDatabase userHistory = mUserState.get(userId); if (userHistory == null) { final File historyDir = new File(Environment.getDataSystemCeDirectory(userId), @@ -242,4 +295,39 @@ public class NotificationHistoryManager { return mUserPendingPackageRemovals.get(userId); } } + + final class SettingsObserver extends ContentObserver { + private final Uri NOTIFICATION_HISTORY_URI + = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_HISTORY_ENABLED); + + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(NOTIFICATION_HISTORY_URI, + false, this, UserHandle.USER_ALL); + synchronized (mLock) { + for (UserInfo userInfo : mUserManager.getUsers()) { + update(null, userInfo.id); + } + } + } + + @Override + public void onChange(boolean selfChange, Uri uri, int userId) { + update(uri, userId); + } + + public void update(Uri uri, int userId) { + ContentResolver resolver = mContext.getContentResolver(); + if (uri == null || NOTIFICATION_HISTORY_URI.equals(uri)) { + boolean historyEnabled = Settings.Secure.getIntForUser(resolver, + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, userId) + != 0; + onHistoryEnabledChanged(userId, historyEnabled); + } + } + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java index aa3c4659c413e..92c05466deb5d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java @@ -15,11 +15,12 @@ */ package com.android.server.notification; -import static android.os.UserHandle.USER_ALL; +import static android.os.UserHandle.MIN_SECONDARY_USER_ID; import static android.os.UserHandle.USER_SYSTEM; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -28,9 +29,11 @@ import static org.mockito.Mockito.when; import android.app.NotificationHistory; import android.app.NotificationHistory.HistoricalNotification; -import android.content.Context; +import android.content.pm.UserInfo; import android.graphics.drawable.Icon; +import android.os.Handler; import android.os.UserManager; +import android.provider.Settings; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -44,23 +47,22 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.List; + @RunWith(AndroidJUnit4.class) public class NotificationHistoryManagerTest extends UiServiceTestCase { - @Mock - Context mContext; @Mock UserManager mUserManager; @Mock NotificationHistoryDatabase mDb; + @Mock + Handler mHandler; + List mUsers; NotificationHistoryManager mHistoryManager; - private HistoricalNotification getHistoricalNotification(int index) { - return getHistoricalNotification("package" + index, index); - } - private HistoricalNotification getHistoricalNotification(String packageName, int index) { String expectedChannelName = "channelName" + index; String expectedChannelId = "channelId" + index; @@ -88,13 +90,28 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); - when(mContext.getUser()).thenReturn(getContext().getUser()); - when(mContext.getPackageName()).thenReturn(getContext().getPackageName()); + + getContext().addMockSystemService(UserManager.class, mUserManager); + + mUsers = new ArrayList<>(); + UserInfo userSystem = new UserInfo(); + userSystem.id = USER_SYSTEM; + mUsers.add(userSystem); + UserInfo userAll = new UserInfo(); + userAll.id = MIN_SECONDARY_USER_ID; + mUsers.add(userAll); + mUsers.add(userAll); + when(mUserManager.getUsers()).thenReturn(mUsers); + + for (UserInfo info : mUsers) { + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 1, info.id); + } NotificationHistoryDatabaseFactory.setTestingNotificationHistoryDatabase(mDb); - mHistoryManager = new NotificationHistoryManager(mContext); + mHistoryManager = new NotificationHistoryManager(getContext(), mHandler); + mHistoryManager.onBootPhaseAppsCanStart(); } @Test @@ -107,6 +124,20 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { verify(mDb, times(1)).init(); } + public void testOnUserUnlocked_historyDisabled() { + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); + assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); + + mHistoryManager.onUserUnlocked(USER_SYSTEM); + + assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); + assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); + verify(mDb, times(1)).disableHistory(); + } + @Test public void testOnUserUnlocked_cleansUpRemovedPackages() { String pkg = "pkg"; @@ -144,6 +175,7 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); + assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isFalse(); } @Test @@ -186,6 +218,18 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { assertThat(mHistoryManager.getPendingPackageRemovalsForUser(USER_SYSTEM)).contains(pkg); } + @Test + public void testOnPackageRemoved_historyDisabled() { + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + String pkg = "pkg"; + mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg); + + assertThat(mHistoryManager.getPendingPackageRemovalsForUser(USER_SYSTEM)) + .isNull(); + } + @Test public void testOnPackageRemoved_multiUser() { String pkg = "pkg"; @@ -195,8 +239,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.onUserUnlocked(USER_SYSTEM); mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem); - mHistoryManager.onUserUnlocked(USER_ALL); - mHistoryManager.replaceNotificationHistoryDatabase(USER_ALL, userHistoryAll); + mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID); + mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll); mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg); @@ -212,8 +256,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.onUserUnlocked(USER_SYSTEM); mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem); - mHistoryManager.onUserUnlocked(USER_ALL); - mHistoryManager.replaceNotificationHistoryDatabase(USER_ALL, userHistoryAll); + mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID); + mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll); mHistoryManager.triggerWriteToDisk(); @@ -229,9 +273,9 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.onUserUnlocked(USER_SYSTEM); mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem); - mHistoryManager.onUserUnlocked(USER_ALL); - mHistoryManager.replaceNotificationHistoryDatabase(USER_ALL, userHistoryAll); - mHistoryManager.onUserStopped(USER_ALL); + mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID); + mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll); + mHistoryManager.onUserStopped(MIN_SECONDARY_USER_ID); mHistoryManager.triggerWriteToDisk(); @@ -239,6 +283,21 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { verify(userHistoryAll, never()).forceWriteToDisk(); } + @Test + public void testTriggerWriteToDisk_historyDisabled() { + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class); + + mHistoryManager.onUserUnlocked(USER_SYSTEM); + mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem); + + mHistoryManager.triggerWriteToDisk(); + + verify(userHistorySystem, never()).forceWriteToDisk(); + } + @Test public void testAddNotification_userLocked_noCrash() { HistoricalNotification hn = getHistoricalNotification("pkg", 1); @@ -246,10 +305,24 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.addNotification(hn); } + @Test + public void testAddNotification_historyDisabled() { + HistoricalNotification hn = getHistoricalNotification("pkg", 1); + + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, hn.getUserId()); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + + mHistoryManager.onUserUnlocked(hn.getUserId()); + mHistoryManager.addNotification(hn); + + verify(mDb, never()).addNotification(any()); + } + @Test public void testAddNotification() { HistoricalNotification hnSystem = getHistoricalNotification("pkg", USER_SYSTEM); - HistoricalNotification hnAll = getHistoricalNotification("pkg", USER_ALL); + HistoricalNotification hnAll = getHistoricalNotification("pkg", MIN_SECONDARY_USER_ID); NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class); NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class); @@ -257,8 +330,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.onUserUnlocked(USER_SYSTEM); mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem); - mHistoryManager.onUserUnlocked(USER_ALL); - mHistoryManager.replaceNotificationHistoryDatabase(USER_ALL, userHistoryAll); + mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID); + mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll); mHistoryManager.addNotification(hnSystem); mHistoryManager.addNotification(hnAll); @@ -270,7 +343,7 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { @Test public void testReadNotificationHistory() { HistoricalNotification hnSystem = getHistoricalNotification("pkg", USER_SYSTEM); - HistoricalNotification hnAll = getHistoricalNotification("pkg", USER_ALL); + HistoricalNotification hnAll = getHistoricalNotification("pkg", MIN_SECONDARY_USER_ID); NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class); NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class); @@ -283,8 +356,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { when(nhSystem.getNotificationsToWrite()).thenReturn(nhSystemList); when(userHistorySystem.readNotificationHistory()).thenReturn(nhSystem); - mHistoryManager.onUserUnlocked(USER_ALL); - mHistoryManager.replaceNotificationHistoryDatabase(USER_ALL, userHistoryAll); + mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID); + mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll); NotificationHistory nhAll = mock(NotificationHistory.class); ArrayList nhAllList = new ArrayList<>(); nhAllList.add(hnAll); @@ -293,13 +366,47 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { // ensure read history returns both historical notifs NotificationHistory nh = mHistoryManager.readNotificationHistory( - new int[] {USER_SYSTEM, USER_ALL}); + new int[] {USER_SYSTEM, MIN_SECONDARY_USER_ID}); assertThat(nh.getNotificationsToWrite()).contains(hnSystem); assertThat(nh.getNotificationsToWrite()).contains(hnAll); } @Test - public void readFilteredNotificationHistory_userUnlocked() { + public void testReadNotificationHistory_historyDisabled() { + HistoricalNotification hnSystem = getHistoricalNotification("pkg", USER_SYSTEM); + + mHistoryManager.onUserUnlocked(USER_SYSTEM); + NotificationHistory nhSystem = mock(NotificationHistory.class); + ArrayList nhSystemList = new ArrayList<>(); + nhSystemList.add(hnSystem); + when(nhSystem.getNotificationsToWrite()).thenReturn(nhSystemList); + when(mDb.readNotificationHistory()).thenReturn(nhSystem); + + mHistoryManager.onUserUnlocked(USER_SYSTEM); + + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + + NotificationHistory nh = + mHistoryManager.readNotificationHistory(new int[] {USER_SYSTEM,}); + assertThat(nh.getNotificationsToWrite()).isEmpty(); + } + + @Test + public void testReadFilteredNotificationHistory_userLocked() { + NotificationHistory nh = + mHistoryManager.readFilteredNotificationHistory(USER_SYSTEM, "", "", 1000); + assertThat(nh.getNotificationsToWrite()).isEmpty(); + } + + @Test + public void testReadFilteredNotificationHistory_historyDisabled() { + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + + mHistoryManager.onUserUnlocked(USER_SYSTEM); NotificationHistory nh = mHistoryManager.readFilteredNotificationHistory(USER_SYSTEM, "", "", 1000); assertThat(nh.getNotificationsToWrite()).isEmpty(); @@ -312,4 +419,15 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.readFilteredNotificationHistory(USER_SYSTEM, "pkg", "chn", 1000); verify(mDb, times(1)).readNotificationHistory("pkg", "chn", 1000); } + + @Test + public void testIsHistoryEnabled() { + assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue(); + + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); + mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); + + assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isFalse(); + } }