Loading services/core/java/com/android/server/notification/NotificationHistoryManager.java +29 −7 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,8 @@ public class NotificationHistoryManager { private final SparseArray<List<String>> mUserPendingPackageRemovals = new SparseArray<>(); private final SparseArray<List<String>> mUserPendingPackageRemovals = new SparseArray<>(); @GuardedBy("mLock") @GuardedBy("mLock") private final SparseBooleanArray mHistoryEnabled = new SparseBooleanArray(); private final SparseBooleanArray mHistoryEnabled = new SparseBooleanArray(); @GuardedBy("mLock") private final SparseBooleanArray mUserPendingHistoryDisables = new SparseBooleanArray(); public NotificationHistoryManager(Context context, Handler handler) { public NotificationHistoryManager(Context context, Handler handler) { mContext = context; mContext = context; Loading @@ -75,6 +77,11 @@ public class NotificationHistoryManager { mSettingsObserver = new SettingsObserver(handler); mSettingsObserver = new SettingsObserver(handler); } } @VisibleForTesting void onDestroy() { mSettingsObserver.stopObserving(); } void onBootPhaseAppsCanStart() { void onBootPhaseAppsCanStart() { mSettingsObserver.observe(); mSettingsObserver.observe(); } } Loading @@ -99,8 +106,8 @@ public class NotificationHistoryManager { } } // delete history if it was disabled when the user was locked // delete history if it was disabled when the user was locked if (!mHistoryEnabled.get(userId)) { if (mUserPendingHistoryDisables.get(userId)) { userHistory.disableHistory(); disableHistory(userHistory, userId); } } } } } } Loading @@ -118,6 +125,7 @@ public class NotificationHistoryManager { // removed) - we just need clean up our internal state for GC // removed) - we just need clean up our internal state for GC mUserPendingPackageRemovals.put(userId, null); mUserPendingPackageRemovals.put(userId, null); mHistoryEnabled.put(userId, false); mHistoryEnabled.put(userId, false); mUserPendingHistoryDisables.put(userId, false); onUserStopped(userId); onUserStopped(userId); } } } } Loading Loading @@ -213,20 +221,29 @@ public class NotificationHistoryManager { void onHistoryEnabledChanged(@UserIdInt int userId, boolean historyEnabled) { void onHistoryEnabledChanged(@UserIdInt int userId, boolean historyEnabled) { synchronized (mLock) { synchronized (mLock) { if (historyEnabled) { mHistoryEnabled.put(userId, historyEnabled); mHistoryEnabled.put(userId, historyEnabled); } // These requests might fail if the user is locked; onUserUnlocked will pick up those // cases final NotificationHistoryDatabase userHistory = final NotificationHistoryDatabase userHistory = getUserHistoryAndInitializeIfNeededLocked(userId); getUserHistoryAndInitializeIfNeededLocked(userId); if (userHistory != null) { if (userHistory != null) { if (!historyEnabled) { if (!historyEnabled) { userHistory.disableHistory(); disableHistory(userHistory, userId); } } } else { mUserPendingHistoryDisables.put(userId, !historyEnabled); } } } } } } private void disableHistory(NotificationHistoryDatabase userHistory, @UserIdInt int userId) { userHistory.disableHistory(); mUserPendingHistoryDisables.put(userId, false); mHistoryEnabled.put(userId, false); mUserState.put(userId, null); } @GuardedBy("mLock") @GuardedBy("mLock") private @Nullable NotificationHistoryDatabase getUserHistoryAndInitializeIfNeededLocked( private @Nullable NotificationHistoryDatabase getUserHistoryAndInitializeIfNeededLocked( int userId) { int userId) { Loading Loading @@ -316,6 +333,11 @@ public class NotificationHistoryManager { } } } } void stopObserving() { ContentResolver resolver = mContext.getContentResolver(); resolver.unregisterContentObserver(this); } @Override @Override public void onChange(boolean selfChange, Uri uri, int userId) { public void onChange(boolean selfChange, Uri uri, int userId) { update(uri, userId); update(uri, userId); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java +44 −5 Original line number Original line Diff line number Diff line Loading @@ -40,8 +40,8 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; import com.android.server.UiServiceTestCase; import org.junit.After; import org.junit.Before; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mock; Loading Loading @@ -115,6 +115,11 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.onBootPhaseAppsCanStart(); mHistoryManager.onBootPhaseAppsCanStart(); } } @After public void tearDown() { mHistoryManager.onDestroy(); } @Test @Test public void testOnUserUnlocked() { public void testOnUserUnlocked() { assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); Loading @@ -126,21 +131,51 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { } } @Test @Test @Ignore("b/147012298") public void testOnUserUnlocked_historyDisabled() { public void testOnUserUnlocked_historyDisabled() { // create a history mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue(); // lock user mHistoryManager.onUserStopped(USER_SYSTEM); // turn off history Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); // unlock user, verify that history is disabled mHistoryManager.onUserUnlocked(USER_SYSTEM); mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); verify(mDb, times(1)).disableHistory(); verify(mDb, times(1)).disableHistory(); } } @Test public void testOnUserUnlocked_historyDisabledThenEnabled() { // create a history mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue(); // lock user mHistoryManager.onUserStopped(USER_SYSTEM); // turn off history Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); // turn on history Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 1, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); // unlock user, verify that history is NOT disabled mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue(); verify(mDb, never()).disableHistory(); } @Test @Test public void testOnUserUnlocked_cleansUpRemovedPackages() { public void testOnUserUnlocked_cleansUpRemovedPackages() { String pkg = "pkg"; String pkg = "pkg"; Loading Loading @@ -223,6 +258,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { @Test @Test public void testOnPackageRemoved_historyDisabled() { public void testOnPackageRemoved_historyDisabled() { mHistoryManager.onUserUnlocked(USER_SYSTEM); Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); Loading Loading @@ -427,6 +464,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { public void testIsHistoryEnabled() { public void testIsHistoryEnabled() { assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue(); assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue(); mHistoryManager.onUserUnlocked(USER_SYSTEM); Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); Loading Loading
services/core/java/com/android/server/notification/NotificationHistoryManager.java +29 −7 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,8 @@ public class NotificationHistoryManager { private final SparseArray<List<String>> mUserPendingPackageRemovals = new SparseArray<>(); private final SparseArray<List<String>> mUserPendingPackageRemovals = new SparseArray<>(); @GuardedBy("mLock") @GuardedBy("mLock") private final SparseBooleanArray mHistoryEnabled = new SparseBooleanArray(); private final SparseBooleanArray mHistoryEnabled = new SparseBooleanArray(); @GuardedBy("mLock") private final SparseBooleanArray mUserPendingHistoryDisables = new SparseBooleanArray(); public NotificationHistoryManager(Context context, Handler handler) { public NotificationHistoryManager(Context context, Handler handler) { mContext = context; mContext = context; Loading @@ -75,6 +77,11 @@ public class NotificationHistoryManager { mSettingsObserver = new SettingsObserver(handler); mSettingsObserver = new SettingsObserver(handler); } } @VisibleForTesting void onDestroy() { mSettingsObserver.stopObserving(); } void onBootPhaseAppsCanStart() { void onBootPhaseAppsCanStart() { mSettingsObserver.observe(); mSettingsObserver.observe(); } } Loading @@ -99,8 +106,8 @@ public class NotificationHistoryManager { } } // delete history if it was disabled when the user was locked // delete history if it was disabled when the user was locked if (!mHistoryEnabled.get(userId)) { if (mUserPendingHistoryDisables.get(userId)) { userHistory.disableHistory(); disableHistory(userHistory, userId); } } } } } } Loading @@ -118,6 +125,7 @@ public class NotificationHistoryManager { // removed) - we just need clean up our internal state for GC // removed) - we just need clean up our internal state for GC mUserPendingPackageRemovals.put(userId, null); mUserPendingPackageRemovals.put(userId, null); mHistoryEnabled.put(userId, false); mHistoryEnabled.put(userId, false); mUserPendingHistoryDisables.put(userId, false); onUserStopped(userId); onUserStopped(userId); } } } } Loading Loading @@ -213,20 +221,29 @@ public class NotificationHistoryManager { void onHistoryEnabledChanged(@UserIdInt int userId, boolean historyEnabled) { void onHistoryEnabledChanged(@UserIdInt int userId, boolean historyEnabled) { synchronized (mLock) { synchronized (mLock) { if (historyEnabled) { mHistoryEnabled.put(userId, historyEnabled); mHistoryEnabled.put(userId, historyEnabled); } // These requests might fail if the user is locked; onUserUnlocked will pick up those // cases final NotificationHistoryDatabase userHistory = final NotificationHistoryDatabase userHistory = getUserHistoryAndInitializeIfNeededLocked(userId); getUserHistoryAndInitializeIfNeededLocked(userId); if (userHistory != null) { if (userHistory != null) { if (!historyEnabled) { if (!historyEnabled) { userHistory.disableHistory(); disableHistory(userHistory, userId); } } } else { mUserPendingHistoryDisables.put(userId, !historyEnabled); } } } } } } private void disableHistory(NotificationHistoryDatabase userHistory, @UserIdInt int userId) { userHistory.disableHistory(); mUserPendingHistoryDisables.put(userId, false); mHistoryEnabled.put(userId, false); mUserState.put(userId, null); } @GuardedBy("mLock") @GuardedBy("mLock") private @Nullable NotificationHistoryDatabase getUserHistoryAndInitializeIfNeededLocked( private @Nullable NotificationHistoryDatabase getUserHistoryAndInitializeIfNeededLocked( int userId) { int userId) { Loading Loading @@ -316,6 +333,11 @@ public class NotificationHistoryManager { } } } } void stopObserving() { ContentResolver resolver = mContext.getContentResolver(); resolver.unregisterContentObserver(this); } @Override @Override public void onChange(boolean selfChange, Uri uri, int userId) { public void onChange(boolean selfChange, Uri uri, int userId) { update(uri, userId); update(uri, userId); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java +44 −5 Original line number Original line Diff line number Diff line Loading @@ -40,8 +40,8 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; import com.android.server.UiServiceTestCase; import org.junit.After; import org.junit.Before; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mock; Loading Loading @@ -115,6 +115,11 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { mHistoryManager.onBootPhaseAppsCanStart(); mHistoryManager.onBootPhaseAppsCanStart(); } } @After public void tearDown() { mHistoryManager.onDestroy(); } @Test @Test public void testOnUserUnlocked() { public void testOnUserUnlocked() { assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); Loading @@ -126,21 +131,51 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { } } @Test @Test @Ignore("b/147012298") public void testOnUserUnlocked_historyDisabled() { public void testOnUserUnlocked_historyDisabled() { // create a history mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue(); // lock user mHistoryManager.onUserStopped(USER_SYSTEM); // turn off history Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); // unlock user, verify that history is disabled mHistoryManager.onUserUnlocked(USER_SYSTEM); mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse(); assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse(); verify(mDb, times(1)).disableHistory(); verify(mDb, times(1)).disableHistory(); } } @Test public void testOnUserUnlocked_historyDisabledThenEnabled() { // create a history mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue(); // lock user mHistoryManager.onUserStopped(USER_SYSTEM); // turn off history Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); // turn on history Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 1, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); // unlock user, verify that history is NOT disabled mHistoryManager.onUserUnlocked(USER_SYSTEM); assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue(); verify(mDb, never()).disableHistory(); } @Test @Test public void testOnUserUnlocked_cleansUpRemovedPackages() { public void testOnUserUnlocked_cleansUpRemovedPackages() { String pkg = "pkg"; String pkg = "pkg"; Loading Loading @@ -223,6 +258,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { @Test @Test public void testOnPackageRemoved_historyDisabled() { public void testOnPackageRemoved_historyDisabled() { mHistoryManager.onUserUnlocked(USER_SYSTEM); Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); Loading Loading @@ -427,6 +464,8 @@ public class NotificationHistoryManagerTest extends UiServiceTestCase { public void testIsHistoryEnabled() { public void testIsHistoryEnabled() { assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue(); assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue(); mHistoryManager.onUserUnlocked(USER_SYSTEM); Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM); Loading