Merge "Add Settings flag to turn notif history on/off"

This commit is contained in:
TreeHugger Robot
2019-11-27 09:44:02 +00:00
committed by Android (Google) Code Review
6 changed files with 262 additions and 37 deletions

View File

@@ -8167,6 +8167,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).

View File

@@ -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,

View File

@@ -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);

View File

@@ -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

View File

@@ -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<NotificationHistoryDatabase> mUserState = new SparseArray<>();
@@ -57,19 +66,26 @@ public class NotificationHistoryManager {
// TODO: does this need to be persisted across reboots?
@GuardedBy("mLock")
private final SparseArray<List<String>> 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<String> userPendingRemovals =
mUserPendingPackageRemovals.get(userId, new ArrayList<>());
userPendingRemovals.add(packageName);
mUserPendingPackageRemovals.put(userId, userPendingRemovals);
if (mHistoryEnabled.get(userId, false)) {
List<String> 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);
}
}
}
}

View File

@@ -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<UserInfo> 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<HistoricalNotification> 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<HistoricalNotification> 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();
}
}