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

Commit 14656423 authored by Kodlee Yin's avatar Kodlee Yin
Browse files

Fix compatibility in MessagingStyle.

The changes introduced to add MessagingStyle#isGroupConversation had
an implementation bug wherein an application that targets SDK < P
can set a non-null MessagingStyle#setConversationTitle which, in that
SDK version, would also denote it being a group conversation. A
listener targetting SDK >= P would be able able to capture this
notification, but incorrectly be given false when calling
MessagingStyle#isGroupConversation. This CL adds back legacy
functionality to #isGroupConversation by checking the
application's SDK version when they call #setConversationTitle
and interally set #isGroupConversation to true.

Test: runtest -x
core/tests/coretests/src/android/app/NotificationTest.java
Bug: 67717177

Change-Id: I2233e3d0b6d4fcf9823e50cd7aa31b76bbaddaed
parent 7e3cae85
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -5994,8 +5994,15 @@ public class Notification implements Parcelable
        /**
         * Sets the title to be displayed on this conversation. May be set to {@code null}.
         *
         * @param conversationTitle A name for the conversation, or {@code null}
         * @return this object for method chaining.
         * <p>This API's behavior was changed in SDK version {@link Build.VERSION_CODES#P}. If your
         * application's target version is less than {@link Build.VERSION_CODES#P}, setting a
         * conversation title to a non-null value will make {@link #isGroupConversation()} return
         * {@code true} and passing {@code null} will make it return {@code false}. In
         * {@link Build.VERSION_CODES#P} and beyond, use {@link #setGroupConversation(boolean)}
         * to set group conversation status.
         *
         * @param conversationTitle Title displayed for this conversation
         * @return this object for method chaining
         */
        public MessagingStyle setConversationTitle(@Nullable CharSequence conversationTitle) {
            mConversationTitle = conversationTitle;
@@ -6083,6 +6090,7 @@ public class Notification implements Parcelable

        /**
         * Sets whether this conversation notification represents a group.
         *
         * @param isGroupConversation {@code true} if the conversation represents a group,
         * {@code false} otherwise.
         * @return this object for method chaining
@@ -6093,9 +6101,27 @@ public class Notification implements Parcelable
        }

        /**
         * Returns {@code true} if this notification represents a group conversation.
         * Returns {@code true} if this notification represents a group conversation, otherwise
         * {@code false}.
         *
         * <p> If the application that generated this {@link MessagingStyle} targets an SDK version
         * less than {@link Build.VERSION_CODES#P}, this method becomes dependent on whether or
         * not the conversation title is set; returning {@code true} if the conversation title is
         * a non-null value, or {@code false} otherwise. From {@link Build.VERSION_CODES#P} forward,
         * this method returns what's set by {@link #setGroupConversation(boolean)} allowing for
         * named, non-group conversations.
         *
         * @see #setConversationTitle(CharSequence)
         */
        public boolean isGroupConversation() {
            // When target SDK version is < P, a non-null conversation title dictates if this is
            // as group conversation.
            if (mBuilder != null
                    && mBuilder.mContext.getApplicationInfo().targetSdkVersion
                            < Build.VERSION_CODES.P) {
                return mConversationTitle != null;
            }

            return mIsGroupConversation;
        }

+55 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.test.InstrumentationRegistry;
@@ -215,9 +216,11 @@ public class NotificationTest {
    }

    @Test
    public void testMessagingStyle_isGroupConversation() {
    public void messagingStyle_isGroupConversation() {
        mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.P;
        Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name")
                .setGroupConversation(true);
                .setGroupConversation(true)
                .setConversationTitle("test conversation title");
        Notification notification = new Notification.Builder(mContext, "test id")
                .setSmallIcon(1)
                .setContentTitle("test title")
@@ -228,6 +231,56 @@ public class NotificationTest {
        assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION));
    }

    @Test
    public void messagingStyle_isGroupConversation_noConversationTitle() {
        mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.P;
        Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name")
                .setGroupConversation(true)
                .setConversationTitle(null);
        Notification notification = new Notification.Builder(mContext, "test id")
                .setSmallIcon(1)
                .setContentTitle("test title")
                .setStyle(messagingStyle)
                .build();

        assertTrue(messagingStyle.isGroupConversation());
        assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION));
    }

    @Test
    public void messagingStyle_isGroupConversation_withConversationTitle_legacy() {
        // In legacy (version < P), isGroupConversation is controlled by conversationTitle.
        mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.O;
        Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name")
                .setGroupConversation(false)
                .setConversationTitle("test conversation title");
        Notification notification = new Notification.Builder(mContext, "test id")
                .setSmallIcon(1)
                .setContentTitle("test title")
                .setStyle(messagingStyle)
                .build();

        assertTrue(messagingStyle.isGroupConversation());
        assertFalse(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION));
    }

    @Test
    public void messagingStyle_isGroupConversation_withoutConversationTitle_legacy() {
        // In legacy (version < P), isGroupConversation is controlled by conversationTitle.
        mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.O;
        Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name")
                .setGroupConversation(true)
                .setConversationTitle(null);
        Notification notification = new Notification.Builder(mContext, "test id")
                .setSmallIcon(1)
                .setContentTitle("test title")
                .setStyle(messagingStyle)
                .build();

        assertFalse(messagingStyle.isGroupConversation());
        assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION));
    }

    private Notification.Builder getMediaNotification() {
        MediaSession session = new MediaSession(mContext, "test");
        return new Notification.Builder(mContext, "color")