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

Commit bd13acd7 authored by Matías Hernández's avatar Matías Hernández
Browse files

Use random ids when creating conversation channels for a package

This ensures we don't exceed the 1000-character limit (which could even end up replacing another conversation channel with a common prefix).

Bug: 432250872
Test: atest NotificationManagerServiceTest
Flag: com.android.server.notification.random_conversation_ids
Change-Id: Ifdebb94e8ba4bcadf8e153c0bbbccb0db0fd7797
parent d917e7b4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -124,7 +124,8 @@ public final class NotificationChannel implements Parcelable {
     * {@link ShortcutInfo#getId() id} of the conversation.
     * @hide
     */
    public static final String CONVERSATION_CHANNEL_ID_FORMAT = "%1$s : %2$s";
    // TODO: b/432250872 - Delete when inlining random_conversation_ids flag.
    public static final String OLD_CONVERSATION_CHANNEL_ID_FORMAT = "%1$s : %2$s";

    /**
     * TODO: STOPSHIP  remove
+15 −6
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ import static android.app.Notification.FLAG_ONGOING_EVENT;
import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
import static android.app.Notification.FLAG_PROMOTED_ONGOING;
import static android.app.Notification.FLAG_USER_INITIATED_JOB;
import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
import static android.app.NotificationChannel.OLD_CONVERSATION_CHANNEL_ID_FORMAT;
import static android.app.NotificationChannel.SYSTEM_RESERVED_IDS;
import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED;
@@ -449,6 +449,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
@@ -5162,8 +5163,12 @@ public class NotificationManagerService extends SystemService {
                }
            }
            NotificationChannel conversationChannel = parentChannel;
            if (Flags.randomConversationIds()) {
                conversationChannel.setId(UUID.randomUUID().toString());
            } else {
                conversationChannel.setId(String.format(
                    CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId));
                        OLD_CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId));
            }
            conversationChannel.setConversationId(parentId, conversationId);
            createNotificationChannelsImpl(
                    pkg, uid, new ParceledListSlice(Arrays.asList(conversationChannel)));
@@ -7422,10 +7427,14 @@ public class NotificationManagerService extends SystemService {
                return previous;
            }
            String conversationChannelId = String.format(CONVERSATION_CHANNEL_ID_FORMAT, parentId,
                    conversationId);
            NotificationChannel conversationChannel = parentChannel.copy();
            conversationChannel.setId(conversationChannelId);
            if (Flags.randomConversationIds()) {
                conversationChannel.setId(UUID.randomUUID().toString());
            } else {
                conversationChannel.setId(
                        String.format(OLD_CONVERSATION_CHANNEL_ID_FORMAT, parentId,
                                conversationId));
            }
            conversationChannel.setConversationId(parentId, conversationId);
            createNotificationChannelsImpl(
                    pkg, uid, new ParceledListSlice<>(Arrays.asList(conversationChannel)));
+6 −1
Original line number Diff line number Diff line
@@ -221,4 +221,9 @@ flag {
  }
}

flag {
  name: "random_conversation_ids"
  namespace: "systemui"
  description: "Use random ids for new conversation channels, instead of concatenating parent id and conversation id"
  bug: "432250872"
}
+27 −0
Original line number Diff line number Diff line
@@ -5249,6 +5249,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertThat(again).isSameInstanceAs(created);
    }
    @Test
    @EnableFlags({FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT,
            Flags.FLAG_RANDOM_CONVERSATION_IDS})
    public void createConvChannelForPkgFromPrivilegedListener_longParentId_differentChannels()
            throws Exception {
        String extremelyLongParentId = "x".repeat(NotificationChannel.MAX_TEXT_LENGTH - 1);
        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                .thenReturn(singletonList(mock(AssociationInfo.class)));
        mService.mPreferencesHelper.createNotificationChannel(mPkg, mUid,
                new NotificationChannel(extremelyLongParentId, "parentName", IMPORTANCE_DEFAULT),
                true, false, mUid, false);
        NotificationChannel convoChannel1 = mBinderService
                .createConversationNotificationChannelForPackageFromPrivilegedListener(
                        null, mPkg, mUser, extremelyLongParentId, "convo1");
        NotificationChannel convoChannel2 = mBinderService
                .createConversationNotificationChannelForPackageFromPrivilegedListener(
                        null, mPkg, mUser, extremelyLongParentId, "convo2");
        assertThat(convoChannel1).isNotNull();
        assertThat(convoChannel2).isNotNull();
        assertThat(convoChannel1.getId()).isNotEqualTo(convoChannel2.getId());
        ParceledListSlice<NotificationChannel> channels = mBinderService.getNotificationChannels(
                mPkg, mPkg, mUserId);
        assertThat(channels.getList().stream().filter(c -> c.isConversation()).toList()).hasSize(2);
    }
    @Test
    public void updateNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
+17 −27
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import static android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI;
import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.Notification.VISIBILITY_SECRET;
import static android.app.NotificationChannel.ALLOW_BUBBLE_ON;
import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE;
import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.PROMOTIONS_ID;
@@ -181,6 +180,9 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
@@ -201,9 +203,6 @@ import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

@SmallTest
@RunWith(ParameterizedAndroidJunit4.class)
public class PreferencesHelperTest extends UiServiceTestCase {
@@ -5123,9 +5122,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false,
                UID_O, false);

        NotificationChannel friend = new NotificationChannel(String.format(
                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
                "messages", IMPORTANCE_DEFAULT);
        NotificationChannel friend = new NotificationChannel("friendConvo", "messages",
                IMPORTANCE_DEFAULT);
        friend.setConversationId(parent.getId(), conversationId);
        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false,
                UID_O, false);
@@ -5151,19 +5149,15 @@ public class PreferencesHelperTest extends UiServiceTestCase {
    public void testConversationNotificationChannelsRequireParents() {
        String parentId = "does not exist";
        String conversationId = "friend";

        NotificationChannel friend = new NotificationChannel(String.format(
                CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId),
                "messages", IMPORTANCE_DEFAULT);
        NotificationChannel friend = new NotificationChannel("friendConvo", "messages",
                IMPORTANCE_DEFAULT);
        friend.setConversationId(parentId, conversationId);

        try {
            mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false,
                    UID_O, false);
            fail("allowed creation of conversation channel without a parent");
        } catch (IllegalArgumentException e) {
            // good
        }
        IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () ->
                mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false, UID_O, false));

        assertThat(e).hasMessageThat().isEqualTo(
                "Tried to create a conversation channel without a preexisting parent");
    }

    @Test
@@ -6058,8 +6052,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);

        String channelId = String.format(
                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
        String channelId = "conversationChannel";
        String name = "conversation";
        NotificationChannel friend = new NotificationChannel(channelId,
                name, IMPORTANCE_DEFAULT);
@@ -6091,8 +6084,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        NotificationChannel parent =
                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
        String channelId = String.format(
                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
        String channelId = "conversationChannel";
        NotificationChannel friend = new NotificationChannel(channelId,
                "conversation", IMPORTANCE_DEFAULT);
        friend.setConversationId(parent.getId(), "friend");
@@ -6122,8 +6114,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        NotificationChannel parent =
                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
        String channelId = String.format(
                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
        String channelId = "conversationChannel";
        NotificationChannel friend = new NotificationChannel(channelId,
                "conversation", IMPORTANCE_DEFAULT);
        friend.setConversationId(parent.getId(), "friend");
@@ -6743,8 +6734,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.resetCacheInvalidation();
        String parentId = "id";
        String convId = "conversation";
        NotificationChannel conv = new NotificationChannel(
                String.format(CONVERSATION_CHANNEL_ID_FORMAT, parentId, convId), "conversation",
        NotificationChannel conv = new NotificationChannel("convId", "conversation",
                IMPORTANCE_DEFAULT);
        conv.setConversationId(parentId, convId);
        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, conv, true, false, UID_N_MR1,
@@ -6812,7 +6802,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        // pkg O, work (same channel ID, different user)
        // pkg N_MR1, user
        // pkg N_MR1, user, conversation child of above
        String p2u1ConvId = String.format(CONVERSATION_CHANNEL_ID_FORMAT, "p2", "conv");
        String p2u1ConvId = "p2conv";
        NotificationChannel p1u1 = new NotificationChannel("p1", "p1u1", IMPORTANCE_DEFAULT);
        NotificationChannel p1u2 = new NotificationChannel("p1", "p1u2", IMPORTANCE_DEFAULT);
        NotificationChannel p2u1 = new NotificationChannel("p2", "p2u1", IMPORTANCE_DEFAULT);