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

Commit b7adedee authored by Iavor-Valentin Iftime's avatar Iavor-Valentin Iftime Committed by Android (Google) Code Review
Browse files

Merge "Restore deleted conversation channel on notification posted" into main

parents 1daf1924 d770dd1c
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -7042,9 +7042,8 @@ public class NotificationManagerService extends SystemService {
            channelId = (new Notification.TvExtender(notification)).getChannelId();
        }
        String shortcutId = n.getShortcutId();
        final NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel(
                pkg, notificationUid, channelId, shortcutId,
                true /* parent ok */, false /* includeDeleted */);
        final NotificationChannel channel = getNotificationChannelRestoreDeleted(pkg,
                callingUid, notificationUid, channelId, shortcutId);
        if (channel == null) {
            final String noChannelStr = "No Channel found for "
                    + "pkg=" + pkg
@@ -7162,6 +7161,35 @@ public class NotificationManagerService extends SystemService {
        return true;
    }
    /**
     * Returns a channel, if exists, and restores deleted conversation channels.
     */
    @Nullable
    private NotificationChannel getNotificationChannelRestoreDeleted(String pkg,
            int callingUid, int notificationUid, String channelId, String conversationId) {
        // Restore a deleted conversation channel, if exists. Otherwise use the parent channel.
        NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel(
                pkg, notificationUid, channelId, conversationId,
                true /* parent ok */, !TextUtils.isEmpty(conversationId) /* includeDeleted */);
        // Restore deleted conversation channel
        if (channel != null && channel.isDeleted()) {
            if (Objects.equals(conversationId, channel.getConversationId())) {
                boolean needsPolicyFileChange = mPreferencesHelper.createNotificationChannel(
                        pkg, notificationUid, channel, true /* fromTargetApp */,
                        mConditionProviders.isPackageOrComponentAllowed(pkg,
                        UserHandle.getUserId(notificationUid)), callingUid, true);
                // Update policy file if the conversation channel was restored
                if (needsPolicyFileChange) {
                    handleSavePolicyFile();
                }
            } else {
                // Do not restore parent channel
                channel = null;
            }
        }
        return channel;
    }
    private void onConversationRemovedInternal(String pkg, int uid, Set<String> shortcuts) {
        checkCallerIsSystem();
        Preconditions.checkStringNotEmpty(pkg);
+169 −1
Original line number Diff line number Diff line
@@ -9926,6 +9926,174 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertEquals(PRIORITY_CATEGORY_CALLS, actual);
    }
    @Test
    public void testRestoreConversationChannel_deleted() throws Exception {
        // Create parent channel
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        final NotificationChannel originalChannel = new NotificationChannel("id", "name",
                IMPORTANCE_DEFAULT);
        NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                NotificationChannel.CREATOR);
        assertEquals(originalChannel, parentChannel);
        mBinderService.createNotificationChannels(PKG,
                new ParceledListSlice(Arrays.asList(parentChannel)));
        //Create deleted conversation channel
        mBinderService.createConversationNotificationChannelForPackage(
                PKG, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
        final NotificationChannel conversationChannel =
                mBinderService.getConversationNotificationChannel(
                PKG, mUserId, PKG, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
        conversationChannel.setDeleted(true);
        //Create notification record
        Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                null /* groupKey */, false /* isSummary */);
        nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
        nb.setChannelId(originalChannel.getId());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
                "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
        assertThat(nr.getChannel()).isEqualTo(originalChannel);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // Verify that the channel was changed to the conversation channel and restored
        assertThat(mService.getNotificationRecord(nr.getKey()).isConversation()).isTrue();
        assertThat(mService.getNotificationRecord(nr.getKey()).getChannel()).isEqualTo(
                conversationChannel);
        assertThat(mService.getNotificationRecord(nr.getKey()).getChannel().isDeleted()).isFalse();
        assertThat(mService.getNotificationRecord(nr.getKey()).getChannel().getDeletedTimeMs())
                .isEqualTo(-1);
    }
    @Test
    public void testDoNotRestoreParentChannel_deleted() throws Exception {
        // Create parent channel and set as deleted
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        final NotificationChannel originalChannel = new NotificationChannel("id", "name",
                IMPORTANCE_DEFAULT);
        NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                NotificationChannel.CREATOR);
        assertEquals(originalChannel, parentChannel);
        mBinderService.createNotificationChannels(PKG,
                new ParceledListSlice(Arrays.asList(parentChannel)));
        parentChannel.setDeleted(true);
        //Create notification record
        Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                null /* groupKey */, false /* isSummary */);
        nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
        nb.setChannelId(originalChannel.getId());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
                "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
        assertThat(nr.getChannel()).isEqualTo(originalChannel);
        when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // Verify that the channel was not restored and the notification was not posted
        assertThat(mService.mChannelToastsSent).contains(mUid);
        assertThat(mService.getNotificationRecord(nr.getKey())).isNull();
        assertThat(parentChannel.isDeleted()).isTrue();
    }
    @Test
    public void testEnqueueToConversationChannel_notDeleted_doesNotRestore() throws Exception {
        TestableNotificationManagerService service = spy(mService);
        PreferencesHelper preferencesHelper = spy(mService.mPreferencesHelper);
        service.setPreferencesHelper(preferencesHelper);
        // Create parent channel
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        final NotificationChannel originalChannel = new NotificationChannel("id", "name",
                IMPORTANCE_DEFAULT);
        NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                NotificationChannel.CREATOR);
        assertEquals(originalChannel, parentChannel);
        mBinderService.createNotificationChannels(PKG,
                new ParceledListSlice(Arrays.asList(parentChannel)));
        //Create conversation channel
        mBinderService.createConversationNotificationChannelForPackage(
                PKG, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
        final NotificationChannel conversationChannel =
                mBinderService.getConversationNotificationChannel(
                    PKG, mUserId, PKG, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
        //Create notification record
        Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                null /* groupKey */, false /* isSummary */);
        nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
        nb.setChannelId(originalChannel.getId());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
                "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
        assertThat(nr.getChannel()).isEqualTo(originalChannel);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // Verify that the channel was changed to the conversation channel and not restored
        assertThat(service.getNotificationRecord(nr.getKey()).isConversation()).isTrue();
        assertThat(service.getNotificationRecord(nr.getKey()).getChannel()).isEqualTo(
                conversationChannel);
        verify(service, never()).handleSavePolicyFile();
        verify(preferencesHelper, never()).createNotificationChannel(anyString(),
                anyInt(), any(), anyBoolean(), anyBoolean(), anyInt(), anyBoolean());
    }
    @Test
    public void testEnqueueToParentChannel_notDeleted_doesNotRestore() throws Exception {
        TestableNotificationManagerService service = spy(mService);
        PreferencesHelper preferencesHelper = spy(mService.mPreferencesHelper);
        service.setPreferencesHelper(preferencesHelper);
        // Create parent channel
        when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
        final NotificationChannel originalChannel = new NotificationChannel("id", "name",
                IMPORTANCE_DEFAULT);
        NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                NotificationChannel.CREATOR);
        assertEquals(originalChannel, parentChannel);
        mBinderService.createNotificationChannels(PKG,
                new ParceledListSlice(Arrays.asList(parentChannel)));
        //Create deleted conversation channel
        mBinderService.createConversationNotificationChannelForPackage(
                PKG, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
        final NotificationChannel conversationChannel =
                mBinderService.getConversationNotificationChannel(
                    PKG, mUserId, PKG, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
        //Create notification record without a shortcutId
        Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                null /* groupKey */, false /* isSummary */);
        nb.setShortcutId(null);
        nb.setChannelId(originalChannel.getId());
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
                "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
        NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
        assertThat(nr.getChannel()).isEqualTo(originalChannel);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // Verify that the channel is the parent channel and no channel was restored
        //assertThat(service.getNotificationRecord(nr.getKey()).isConversation()).isFalse();
        assertThat(service.getNotificationRecord(nr.getKey()).getChannel()).isEqualTo(
                parentChannel);
        verify(service, never()).handleSavePolicyFile();
        verify(preferencesHelper, never()).createNotificationChannel(anyString(),
                anyInt(), any(), anyBoolean(), anyBoolean(), anyInt(), anyBoolean());
    }
    @Test
    public void testGetConversationsForPackage_hasShortcut() throws Exception {
        mService.setPreferencesHelper(mPreferencesHelper);