From 7b05f8abbe931f610a5c2ca913e33ce8cadbe3f2 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 9 Dec 2021 09:59:01 -0500 Subject: [PATCH] Fix some issues reading xml - When migrating the app level permission, use the correct user from the uid - When restoring, don't migrate the permission until the package is installed and we have a correct uid Test: PreferencesHelperTest; manual flag flip and verifying app level settings in the bugreport Bug: 194833441 Change-Id: Ia4f9ff563cecaa58ce8ae2c36c5aaad816169863 --- .../notification/PreferencesHelper.java | 50 ++++-- .../notification/PreferencesHelperTest.java | 158 ++++++++++++++---- 2 files changed, 159 insertions(+), 49 deletions(-) diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 189ac586e533b..7d4877cdc7ee2 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -65,6 +65,7 @@ import android.util.TypedXmlSerializer; import android.util.proto.ProtoOutputStream; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.util.Preconditions; @@ -380,18 +381,16 @@ public class PreferencesHelper implements RankingConfig { } if (migrateToPermission) { - boolean hasChangedChannel = false; - for (NotificationChannel channel : r.channels.values()) { - if (channel.getUserLockedFields() != 0) { - hasChangedChannel = true; - break; - } + r.importance = appImportance; + if (r.uid != UNKNOWN_UID) { + // Don't call into permission system until we have a valid uid + PackagePermission pkgPerm = new PackagePermission( + r.pkg, UserHandle.getUserId(r.uid), + r.importance != IMPORTANCE_NONE, + hasUserConfiguredSettings(r)); + pkgPerms.add(pkgPerm); } - PackagePermission pkgPerm = new PackagePermission( - r.pkg, userId, appImportance != IMPORTANCE_NONE, - hasChangedChannel || appImportance == IMPORTANCE_NONE); - pkgPerms.add(pkgPerm); - } else { + } else if (!mPermissionHelper.isMigrationEnabled()) { r.importance = appImportance; } } @@ -401,11 +400,27 @@ public class PreferencesHelper implements RankingConfig { } if (migrateToPermission) { for (PackagePermission p : pkgPerms) { - mPermissionHelper.setNotificationPermission(p); + try { + mPermissionHelper.setNotificationPermission(p); + } catch (Exception e) { + Slog.e(TAG, "could not migrate setting for " + p.packageName, e); + } } } } + @GuardedBy("mPackagePreferences") + private boolean hasUserConfiguredSettings(PackagePreferences p){ + boolean hasChangedChannel = false; + for (NotificationChannel channel : p.channels.values()) { + if (channel.getUserLockedFields() != 0) { + hasChangedChannel = true; + break; + } + } + return hasChangedChannel || p.importance == IMPORTANCE_NONE; + } + private boolean isShortcutOk(NotificationChannel channel) { boolean isInvalidShortcutChannel = channel.getConversationId() != null && @@ -2526,6 +2541,17 @@ public class PreferencesHelper implements RankingConfig { synchronized (mPackagePreferences) { mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r); } + if (mPermissionHelper.isMigrationEnabled()) { + try { + PackagePermission p = new PackagePermission( + r.pkg, UserHandle.getUserId(r.uid), + r.importance != IMPORTANCE_NONE, + hasUserConfiguredSettings(r)); + mPermissionHelper.setNotificationPermission(p); + } catch (Exception e) { + Slog.e(TAG, "could not migrate setting for " + r.pkg, e); + } + } updated = true; } catch (PackageManager.NameNotFoundException e) { // noop diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index c85e8768de0d3..e8a279907c5e5 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -31,6 +31,7 @@ import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static android.media.AudioAttributes.CONTENT_TYPE_SONIFICATION; import static android.media.AudioAttributes.USAGE_NOTIFICATION; +import static android.os.UserHandle.USER_SYSTEM; import static android.util.StatsLog.ANNOTATION_ID_IS_UID; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES; @@ -545,14 +546,14 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, - UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(), + USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID); mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O}, new int[]{UID_N_MR1, UID_O}); mHelper.setShowBadge(PKG_O, UID_O, true); - loadStreamXml(baos, true, UserHandle.USER_SYSTEM); + loadStreamXml(baos, true, USER_SYSTEM); assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O)); assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); @@ -597,17 +598,22 @@ public class PreferencesHelperTest extends UiServiceTestCase { mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); String xml = "\n" - + "\n" + + "\n" + "\n" + "\n" + "\n" - + "\n" + + "\n" + "\n" + "\n" - + "\n" + + "\n" + "\n" + "\n" + "\n"; + + loadByteArrayXml(xml.getBytes(), false, USER_SYSTEM); + + // expected values NotificationChannel idn = new NotificationChannel("idn", "name", IMPORTANCE_LOW); idn.setSound(null, new AudioAttributes.Builder() .setUsage(USAGE_NOTIFICATION) @@ -637,8 +643,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // Notifications enabled, user set b/c channel modified PackagePermission pExpected = new PackagePermission(PKG_P, 0, true, true); - loadByteArrayXml(xml.getBytes(), true, UserHandle.USER_SYSTEM); - + // verify data assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); assertEquals(idn, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, idn.getId(), false)); @@ -650,6 +655,85 @@ public class PreferencesHelperTest extends UiServiceTestCase { verify(mPermissionHelper).setNotificationPermission(pExpected); } + @Test + public void testReadXml_oldXml_backup_migratesWhenPkgInstalled() throws Exception { + when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, + mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); + + when(mPm.getPackageUidAsUser("pkg1", USER_SYSTEM)).thenReturn(UNKNOWN_UID); + when(mPm.getPackageUidAsUser("pkg2", USER_SYSTEM)).thenReturn(UNKNOWN_UID); + when(mPm.getPackageUidAsUser("pkg3", USER_SYSTEM)).thenReturn(UNKNOWN_UID); + when(mPm.getApplicationInfoAsUser(eq("pkg1"), anyInt(), anyInt())).thenThrow( + new PackageManager.NameNotFoundException()); + when(mPm.getApplicationInfoAsUser(eq("pkg2"), anyInt(), anyInt())).thenThrow( + new PackageManager.NameNotFoundException()); + when(mPm.getApplicationInfoAsUser(eq("pkg3"), anyInt(), anyInt())).thenThrow( + new PackageManager.NameNotFoundException()); + + String xml = "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n"; + NotificationChannel idn = new NotificationChannel("idn", "name", IMPORTANCE_LOW); + idn.setSound(null, new AudioAttributes.Builder() + .setUsage(USAGE_NOTIFICATION) + .setContentType(CONTENT_TYPE_SONIFICATION) + .setFlags(0) + .build()); + idn.setShowBadge(false); + NotificationChannel ido = new NotificationChannel("ido", "name2", IMPORTANCE_LOW); + ido.setShowBadge(true); + ido.setSound(null, new AudioAttributes.Builder() + .setUsage(USAGE_NOTIFICATION) + .setContentType(CONTENT_TYPE_SONIFICATION) + .setFlags(0) + .build()); + NotificationChannel idp = new NotificationChannel("idp", "name3", IMPORTANCE_HIGH); + idp.lockFields(2); + idp.setSound(null, new AudioAttributes.Builder() + .setUsage(USAGE_NOTIFICATION) + .setContentType(CONTENT_TYPE_SONIFICATION) + .setFlags(0) + .build()); + + // Notifications enabled, not user set + PackagePermission pkg1Expected = new PackagePermission("pkg1", 0, true, false); + // Notifications not enabled, so user set + PackagePermission pkg2Expected = new PackagePermission("pkg2", 0, false, true); + // Notifications enabled, user set b/c channel modified + PackagePermission pkg3Expected = new PackagePermission("pkg3", 0, true, true); + + loadByteArrayXml(xml.getBytes(), true, USER_SYSTEM); + + verify(mPermissionHelper, never()).setNotificationPermission(any()); + + when(mPm.getPackageUidAsUser("pkg1", USER_SYSTEM)).thenReturn(11); + when(mPm.getPackageUidAsUser("pkg2", USER_SYSTEM)).thenReturn(12); + when(mPm.getPackageUidAsUser("pkg3", USER_SYSTEM)).thenReturn(13); + + mHelper.onPackagesChanged( + false, 0, new String[]{"pkg1", "pkg2", "pkg3"}, new int[] {11, 12, 13}); + + assertTrue(mHelper.canShowBadge("pkg1", 11)); + + assertEquals(idn, mHelper.getNotificationChannel("pkg1", 11, idn.getId(), false)); + compareChannels(ido, mHelper.getNotificationChannel("pkg2", 12, ido.getId(), false)); + compareChannels(idp, mHelper.getNotificationChannel("pkg3", 13, idp.getId(), false)); + + verify(mPermissionHelper).setNotificationPermission(pkg1Expected); + verify(mPermissionHelper).setNotificationPermission(pkg2Expected); + verify(mPermissionHelper).setNotificationPermission(pkg3Expected); + } + @Test public void testReadXml_newXml_noMigration() throws Exception { when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); @@ -690,7 +774,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { .setFlags(0) .build()); - loadByteArrayXml(xml.getBytes(), true, UserHandle.USER_SYSTEM); + loadByteArrayXml(xml.getBytes(), true, USER_SYSTEM); assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); @@ -714,7 +798,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); appPermissions.put(new Pair(UID_N_MR1, PKG_N_MR1), new Pair(true, false)); - when(mPermissionHelper.getNotificationPermissionValues(UserHandle.USER_SYSTEM)) + when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM)) .thenReturn(appPermissions); NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye"); @@ -748,7 +832,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true); ByteArrayOutputStream baos = writeXmlAndPurge( - PKG_N_MR1, UID_N_MR1, false, UserHandle.USER_SYSTEM); + PKG_N_MR1, UID_N_MR1, false, USER_SYSTEM); String expected = "\n" + "\n" // Importance 0 because off in permissionhelper + ", Pair> appPermissions = new ArrayMap<>(); appPermissions.put(new Pair(UID_P, PKG_P), new Pair(true, false)); appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); - when(mPermissionHelper.getNotificationPermissionValues(UserHandle.USER_SYSTEM)) + when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM)) .thenReturn(appPermissions); NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye"); @@ -912,7 +996,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true); ByteArrayOutputStream baos = writeXmlAndPurge( - PKG_N_MR1, UID_N_MR1, true, UserHandle.USER_SYSTEM); + PKG_N_MR1, UID_N_MR1, true, USER_SYSTEM); String expected = "\n" // Importance 0 because off in permissionhelper + "\n" // Packages that exist solely in permissionhelper + "\n" @@ -986,10 +1070,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, - UserHandle.USER_SYSTEM, channel.getId()); + USER_SYSTEM, channel.getId()); // Testing that in restore we are given the canonical version - loadStreamXml(baos, true, UserHandle.USER_SYSTEM); + loadStreamXml(baos, true, USER_SYSTEM); verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI)); } @@ -1012,9 +1096,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { channel.setSound(SOUND_URI, mAudioAttributes); mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, - UserHandle.USER_SYSTEM, channel.getId()); + USER_SYSTEM, channel.getId()); - loadStreamXml(baos, true, UserHandle.USER_SYSTEM); + loadStreamXml(baos, true, USER_SYSTEM); NotificationChannel actualChannel = mHelper.getNotificationChannel( PKG_N_MR1, UID_N_MR1, channel.getId(), false); @@ -1034,9 +1118,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { channel.setSound(SOUND_URI, mAudioAttributes); mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, - UserHandle.USER_SYSTEM, channel.getId()); + USER_SYSTEM, channel.getId()); - loadStreamXml(baos, true, UserHandle.USER_SYSTEM); + loadStreamXml(baos, true, USER_SYSTEM); NotificationChannel actualChannel = mHelper.getNotificationChannel( PKG_N_MR1, UID_N_MR1, channel.getId(), false); @@ -1065,7 +1149,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "\n"; loadByteArrayXml( - backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM); + backupWithUncanonicalizedSoundUri.getBytes(), true, USER_SYSTEM); NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false); assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound()); @@ -1078,9 +1162,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { channel.setSound(null, mAudioAttributes); mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, - UserHandle.USER_SYSTEM, channel.getId()); + USER_SYSTEM, channel.getId()); - loadStreamXml(baos, true, UserHandle.USER_SYSTEM); + loadStreamXml(baos, true, USER_SYSTEM); NotificationChannel actualChannel = mHelper.getNotificationChannel( PKG_N_MR1, UID_N_MR1, channel.getId(), false); @@ -1111,7 +1195,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false)); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, - UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(), + USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID); mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{ UID_N_MR1}); @@ -1120,7 +1204,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null); parser.nextTag(); - mHelper.readXml(parser, true, UserHandle.USER_SYSTEM); + mHelper.readXml(parser, true, USER_SYSTEM); assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false)); assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false)); @@ -2218,7 +2302,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false); - assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, + assertTrue(mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{UID_N_MR1})); assertEquals(0, mHelper.getNotificationChannels( @@ -2227,7 +2311,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // Not deleted mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false); - assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, + assertFalse(mHelper.onPackagesChanged(false, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{UID_N_MR1})); assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size()); } @@ -2236,7 +2320,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { public void testOnPackageChanged_packageRemoval_importance() throws Exception { mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH); - mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{ + mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{ UID_N_MR1}); assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1, @@ -2250,7 +2334,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2"); mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true); - mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{ + mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{ UID_N_MR1}); assertEquals(0, mHelper.getNotificationChannelGroups( @@ -2267,7 +2351,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1; when(mPm.getApplicationInfoAsUser(eq(PKG_O), anyInt(), anyInt())).thenReturn(legacy); mHelper.onPackagesChanged( - false, UserHandle.USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O}); + false, USER_SYSTEM, new String[]{PKG_O}, new int[]{UID_O}); // make sure the default channel was readded //assertEquals(2, mHelper.getNotificationChannels(PKG_O, UID_O, false).getList().size()); @@ -3224,7 +3308,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); - loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM); + loadByteArrayXml(preQXml.getBytes(), true, USER_SYSTEM); assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS, mHelper.shouldHideSilentStatusIcons()); @@ -4058,7 +4142,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // clear data ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true, - UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID); + USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID); mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{ UID_O}); @@ -4070,7 +4154,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null); parser.nextTag(); - mHelper.readXml(parser, true, UserHandle.USER_SYSTEM); + mHelper.readXml(parser, true, USER_SYSTEM); assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false) .isImportanceLockedByCriticalDeviceFunction()); @@ -4357,7 +4441,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertTrue(nc1.isDeleted()); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_P, UID_P, false, - UserHandle.USER_SYSTEM, "id", NotificationChannel.DEFAULT_CHANNEL_ID); + USER_SYSTEM, "id", NotificationChannel.DEFAULT_CHANNEL_ID); TypedXmlPullParser parser = Xml.newFastPullParser(); parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), @@ -4366,7 +4450,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); - mHelper.readXml(parser, true, UserHandle.USER_SYSTEM); + mHelper.readXml(parser, true, USER_SYSTEM); NotificationChannel nc = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true); assertTrue(DateUtils.isToday(nc.getDeletedTimeMs()));