diff options
6 files changed, 65 insertions, 166 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index b7de997c2600..ca1662e6bfd0 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1870,7 +1870,7 @@ public class Notification implements Parcelable * You can test if a RemoteInput matches these constraints using * {@link RemoteInput#isDataOnly}. */ - static final String EXTRA_DATA_ONLY_INPUTS = "android.extra.DATA_ONLY_INPUTS"; + private static final String EXTRA_DATA_ONLY_INPUTS = "android.extra.DATA_ONLY_INPUTS"; /** * No semantic action defined. @@ -2089,7 +2089,7 @@ public class Notification implements Parcelable * of non-textual RemoteInputs do not access these remote inputs. */ public RemoteInput[] getDataOnlyRemoteInputs() { - return mExtras.getParcelableArray(EXTRA_DATA_ONLY_INPUTS, RemoteInput.class); + return getParcelableArrayFromBundle(mExtras, EXTRA_DATA_ONLY_INPUTS, RemoteInput.class); } /** @@ -2330,8 +2330,8 @@ public class Notification implements Parcelable checkContextualActionNullFields(); ArrayList<RemoteInput> dataOnlyInputs = new ArrayList<>(); - RemoteInput[] previousDataInputs = - mExtras.getParcelableArray(EXTRA_DATA_ONLY_INPUTS, RemoteInput.class); + RemoteInput[] previousDataInputs = getParcelableArrayFromBundle( + mExtras, EXTRA_DATA_ONLY_INPUTS, RemoteInput.class); if (previousDataInputs != null) { for (RemoteInput input : previousDataInputs) { dataOnlyInputs.add(input); @@ -3091,8 +3091,7 @@ public class Notification implements Parcelable visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI))); } - ArrayList<Person> people = - extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class); + ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class); if (people != null && !people.isEmpty()) { for (Person p : people) { p.visitUris(visitor); @@ -3118,8 +3117,8 @@ public class Notification implements Parcelable person.visitUris(visitor); } - final Bundle[] messages = extras.getParcelableArray(EXTRA_MESSAGES, - Bundle.class); + final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES, + Parcelable.class); if (!ArrayUtils.isEmpty(messages)) { for (MessagingStyle.Message message : MessagingStyle.Message .getMessagesFromBundleArray(messages)) { @@ -3127,8 +3126,8 @@ public class Notification implements Parcelable } } - final Bundle[] historic = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES, - Bundle.class); + final Parcelable[] historic = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES, + Parcelable.class); if (!ArrayUtils.isEmpty(historic)) { for (MessagingStyle.Message message : MessagingStyle.Message .getMessagesFromBundleArray(historic)) { @@ -3839,9 +3838,17 @@ public class Notification implements Parcelable */ private void fixDuplicateExtras() { if (extras != null) { - if (mLargeIcon != null) { - extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon); - } + fixDuplicateExtra(mLargeIcon, EXTRA_LARGE_ICON); + } + } + + /** + * If we find an extra that's exactly the same as one of the "real" fields but refers to a + * separate object, replace it with the field's version to avoid holding duplicate copies. + */ + private void fixDuplicateExtra(@Nullable Parcelable original, @NonNull String extraName) { + if (original != null && extras.getParcelable(extraName, Parcelable.class) != null) { + extras.putParcelable(extraName, original); } } @@ -6615,8 +6622,8 @@ public class Notification implements Parcelable big.setViewVisibility(R.id.actions_container, View.GONE); } - RemoteInputHistoryItem[] replyText = mN.extras.getParcelableArray( - EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class); + RemoteInputHistoryItem[] replyText = getParcelableArrayFromBundle( + mN.extras, EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class); if (validRemoteInput && replyText != null && replyText.length > 0 && !TextUtils.isEmpty(replyText[0].getText()) && p.maxRemoteInputHistory > 0) { @@ -8020,7 +8027,8 @@ public class Notification implements Parcelable */ public boolean hasImage() { if (isStyle(MessagingStyle.class) && extras != null) { - final Bundle[] messages = extras.getParcelableArray(EXTRA_MESSAGES, Bundle.class); + final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES, + Parcelable.class); if (!ArrayUtils.isEmpty(messages)) { for (MessagingStyle.Message m : MessagingStyle.Message .getMessagesFromBundleArray(messages)) { @@ -9340,10 +9348,10 @@ public class Notification implements Parcelable mUser = user; } mConversationTitle = extras.getCharSequence(EXTRA_CONVERSATION_TITLE); - Bundle[] messages = extras.getParcelableArray(EXTRA_MESSAGES, Bundle.class); + Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES, Parcelable.class); mMessages = Message.getMessagesFromBundleArray(messages); Parcelable[] histMessages = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES, - Bundle.class); + Parcelable.class); mHistoricMessages = Message.getMessagesFromBundleArray(histMessages); mIsGroupConversation = extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION); mUnreadMessageCount = extras.getInt(EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT); @@ -10210,8 +10218,8 @@ public class Notification implements Parcelable if (mBuilder.mActions.size() > 0) { maxRows--; } - RemoteInputHistoryItem[] remoteInputHistory = mBuilder.mN.extras.getParcelableArray( - EXTRA_REMOTE_INPUT_HISTORY_ITEMS, + RemoteInputHistoryItem[] remoteInputHistory = getParcelableArrayFromBundle( + mBuilder.mN.extras, EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class); if (remoteInputHistory != null && remoteInputHistory.length > NUMBER_OF_HISTORY_ALLOWED_UNTIL_REDUCTION) { @@ -13076,8 +13084,7 @@ public class Notification implements Parcelable public WearableExtender(Notification notif) { Bundle wearableBundle = notif.extras.getBundle(EXTRA_WEARABLE_EXTENSIONS); if (wearableBundle != null) { - List<Action> actions = wearableBundle.getParcelableArrayList( - KEY_ACTIONS, Notification.Action.class); + List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS, android.app.Notification.Action.class); if (actions != null) { mActions.addAll(actions); } @@ -13086,8 +13093,8 @@ public class Notification implements Parcelable mDisplayIntent = wearableBundle.getParcelable( KEY_DISPLAY_INTENT, PendingIntent.class); - Notification[] pages = - wearableBundle.getParcelableArray(KEY_PAGES, Notification.class); + Notification[] pages = getParcelableArrayFromBundle( + wearableBundle, KEY_PAGES, Notification.class); if (pages != null) { Collections.addAll(mPages, pages); } @@ -14022,7 +14029,7 @@ public class Notification implements Parcelable if (mParticipants != null && mParticipants.length > 1) { author = mParticipants[0]; } - Bundle[] messages = new Bundle[mMessages.length]; + Parcelable[] messages = new Parcelable[mMessages.length]; for (int i = 0; i < messages.length; i++) { Bundle m = new Bundle(); m.putString(KEY_TEXT, mMessages[i]); @@ -14044,7 +14051,8 @@ public class Notification implements Parcelable if (b == null) { return null; } - Bundle[] parcelableMessages = b.getParcelableArray(KEY_MESSAGES, Bundle.class); + Parcelable[] parcelableMessages = b.getParcelableArray(KEY_MESSAGES, + Parcelable.class); String[] messages = null; if (parcelableMessages != null) { String[] tmp = new String[parcelableMessages.length]; @@ -14408,6 +14416,27 @@ public class Notification implements Parcelable } } + /** + * Get an array of Parcelable objects from a parcelable array bundle field. + * Update the bundle to have a typed array so fetches in the future don't need + * to do an array copy. + */ + @Nullable + private static <T extends Parcelable> T[] getParcelableArrayFromBundle( + Bundle bundle, String key, Class<T> itemClass) { + final Parcelable[] array = bundle.getParcelableArray(key, Parcelable.class); + final Class<?> arrayClass = Array.newInstance(itemClass, 0).getClass(); + if (arrayClass.isInstance(array) || array == null) { + return (T[]) array; + } + final T[] typedArray = (T[]) Array.newInstance(itemClass, array.length); + for (int i = 0; i < array.length; i++) { + typedArray[i] = (T) array[i]; + } + bundle.putParcelableArray(key, typedArray); + return typedArray; + } + private static class BuilderRemoteViews extends RemoteViews { public BuilderRemoteViews(Parcel parcel) { super(parcel); diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index a2ff4ca0f4a3..23a09857032c 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -16,7 +16,6 @@ package android.app; -import static android.app.Notification.Action.EXTRA_DATA_ONLY_INPUTS; import static android.app.Notification.CarExtender.UnreadConversation.KEY_ON_READ; import static android.app.Notification.CarExtender.UnreadConversation.KEY_ON_REPLY; import static android.app.Notification.CarExtender.UnreadConversation.KEY_REMOTE_INPUT; @@ -98,7 +97,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.style.TextAppearanceSpan; import android.util.Pair; -import android.view.View; import android.widget.RemoteViews; import androidx.test.InstrumentationRegistry; @@ -108,10 +106,10 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.util.ContrastColorUtil; -import libcore.junit.util.compat.CoreCompatChangeRule; - import junit.framework.Assert; +import libcore.junit.util.compat.CoreCompatChangeRule; + import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; @@ -547,22 +545,6 @@ public class NotificationTest { } @Test - public void largeIconMultipleReferences_ignoreBadData() { - Icon originalIcon = Icon.createWithBitmap(BitmapFactory.decodeResource( - mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); - - Notification n = new Notification.Builder(mContext).setLargeIcon(originalIcon).build(); - assertSame(n.getLargeIcon(), originalIcon); - n.extras.putParcelable(EXTRA_LARGE_ICON, new NotificationChannelGroup("hi", "hi")); - - Notification q = writeAndReadParcelable(n); - assertNotSame(q.getLargeIcon(), n.getLargeIcon()); - - assertTrue(q.getLargeIcon().getBitmap().sameAs(n.getLargeIcon().getBitmap())); - assertSame(q.getLargeIcon(), q.extras.getParcelable(EXTRA_LARGE_ICON)); - } - - @Test public void largeIconReferenceInExtrasOnly_keptAfterParcelling() { Icon originalIcon = Icon.createWithBitmap(BitmapFactory.decodeResource( mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); @@ -2462,69 +2444,6 @@ public class NotificationTest { assertThat(progressStyle1.isStyledByProgress()).isTrue(); } - - @Test - public void getDataOnlyRemoteInputs_invalidData() { - Notification.Action action = new Notification.Action.Builder(0, "title", null) - .addRemoteInput(new RemoteInput.Builder("result") - .setAllowFreeFormInput(false) - .setAllowDataType("mimeType", true) - .build()).build(); - action.getExtras().putParcelable(EXTRA_DATA_ONLY_INPUTS, - new NotificationChannelGroup("hi", "hi")); - assertThat(action.getDataOnlyRemoteInputs()).isNull(); - } - - @Test - public void actionAddExtras_invalidData() { - Bundle extras = new Bundle(); - extras.putParcelableArray(EXTRA_DATA_ONLY_INPUTS, - new NotificationChannelGroup[]{new NotificationChannelGroup("hi", "hi")}); - Notification.Action action = new Notification.Action.Builder(0, "title", null) - .addRemoteInput(new RemoteInput.Builder("result") - .setAllowFreeFormInput(false) - .setAllowDataType("mimeType", true) - .addExtras(extras) - .build()).build(); - assertThat(action.getDataOnlyRemoteInputs()[0].getClass()).isEqualTo(RemoteInput.class); - } - - @Test - public void makeBigTemplate_invalidData() { - PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, - new Intent(mContext, NotificationTest.class), - PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - RemoteInput remoteInput = - new RemoteInput.Builder("key_text_reply") - .setLabel("Reply") - .setChoices(new String[]{"Choice 1", "Choice 2"}) - .addExtras(new Bundle()) - .build(); - Notification.Action replyAction = new Notification.Action.Builder( - R.drawable.stat_notify_chat, "Reply", pendingIntent) - .addRemoteInput(remoteInput) - .build(); - - Bundle bundle = new Bundle(); - bundle.putParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - new NotificationChannelGroup[]{}); - - Notification.Builder nb = new Notification.Builder(mContext, "channel") - .setContentTitle("title") - .setVisibility(android.app.Notification.VISIBILITY_PUBLIC) - .setStyle(new Notification.InboxStyle()) - .setExtras(bundle) - .setSmallIcon(R.drawable.stat_notify_chat) - .addAction(replyAction); - - RemoteViews views = nb.createBigContentView(); - View view = views.apply(mContext, null); - assertThat(view.findViewById(R.id.notification_material_reply_container).getVisibility()) - .isNotEqualTo(View.VISIBLE); - assertThat(view.findViewById(R.id.inbox_text0).getVisibility()) - .isNotEqualTo(View.VISIBLE); - } - private void assertValid(Notification.Colors c) { // Assert that all colors are populated assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java index c8ae3586221d..58943ea3b4ee 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java @@ -16,8 +16,6 @@ package com.android.systemui.statusbar; -import static android.app.Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS; - import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -25,7 +23,6 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.app.Notification; -import android.app.NotificationChannelGroup; import android.app.RemoteInputHistoryItem; import android.net.Uri; import android.os.UserHandle; @@ -74,25 +71,6 @@ public class RemoteInputNotificationRebuilderTest extends SysuiTestCase { } @Test - public void testRebuildWithRemoteInput_invalidData() { - Uri uri = mock(Uri.class); - String mimeType = "image/jpeg"; - String text = "image inserted"; - mEntry.getSbn().getNotification().extras.putParcelableArray( - EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - new NotificationChannelGroup[]{}); - StatusBarNotification newSbn = - mRebuilder.rebuildWithRemoteInputInserted( - mEntry, text, false, mimeType, uri); - RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() - .extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); - assertEquals(1, messages.length); - assertEquals(text, messages[0].getText()); - assertEquals(mimeType, messages[0].getMimeType()); - assertEquals(uri, messages[0].getUri()); - } - - @Test public void testRebuildWithRemoteInput_noExistingInput_image() { Uri uri = mock(Uri.class); String mimeType = "image/jpeg"; @@ -101,7 +79,7 @@ public class RemoteInputNotificationRebuilderTest extends SysuiTestCase { mRebuilder.rebuildWithRemoteInputInserted( mEntry, text, false, mimeType, uri); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() - .extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(1, messages.length); assertEquals(text, messages[0].getText()); assertEquals(mimeType, messages[0].getMimeType()); @@ -114,7 +92,7 @@ public class RemoteInputNotificationRebuilderTest extends SysuiTestCase { mRebuilder.rebuildWithRemoteInputInserted( mEntry, "A Reply", false, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() - .extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(1, messages.length); assertEquals("A Reply", messages[0].getText()); assertFalse(newSbn.getNotification().extras @@ -129,7 +107,7 @@ public class RemoteInputNotificationRebuilderTest extends SysuiTestCase { mRebuilder.rebuildWithRemoteInputInserted( mEntry, "A Reply", true, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() - .extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(1, messages.length); assertEquals("A Reply", messages[0].getText()); assertTrue(newSbn.getNotification().extras @@ -152,7 +130,7 @@ public class RemoteInputNotificationRebuilderTest extends SysuiTestCase { newSbn = mRebuilder.rebuildWithRemoteInputInserted( entry, "Reply 2", true, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() - .extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(2, messages.length); assertEquals("Reply 2", messages[0].getText()); assertEquals("A Reply", messages[1].getText()); @@ -175,7 +153,7 @@ public class RemoteInputNotificationRebuilderTest extends SysuiTestCase { newSbn = mRebuilder.rebuildWithRemoteInputInserted( entry, "Reply 2", true, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() - .extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(2, messages.length); assertEquals("Reply 2", messages[0].getText()); assertEquals(text, messages[1].getText()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilder.java index 31022d578b5f..321b6084831e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilder.java @@ -128,8 +128,7 @@ public class RemoteInputNotificationRebuilder { // Read the whole remoteInputs list from the entry, then append all of those to the sbn. Parcelable[] oldHistoryItems = sbn.getNotification().extras - .getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - RemoteInputHistoryItem.class); + .getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); RemoteInputHistoryItem[] newHistoryItems = oldHistoryItems != null ? Stream.concat( @@ -145,8 +144,7 @@ public class RemoteInputNotificationRebuilder { ? new RemoteInputHistoryItem(mimeType, uri, remoteInputText) : new RemoteInputHistoryItem(remoteInputText); Parcelable[] oldHistoryItems = sbn.getNotification().extras - .getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - RemoteInputHistoryItem.class); + .getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); RemoteInputHistoryItem[] newHistoryItems = oldHistoryItems != null ? Stream.concat( Stream.of(newItem), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 205c42f3c2f3..e74ed8d27ec2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -586,8 +586,7 @@ public final class NotificationEntry extends ListEntry { } Bundle extras = mSbn.getNotification().extras; Parcelable[] replyTexts = - extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - RemoteInputHistoryItem.class); + extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); if (!ArrayUtils.isEmpty(replyTexts)) { return true; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 31c650d861ae..72d1db3affe8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -36,7 +36,6 @@ import static org.mockito.Mockito.mock; import android.app.ActivityManager; import android.app.Notification; import android.app.NotificationChannel; -import android.app.NotificationChannelGroup; import android.app.PendingIntent; import android.app.Person; import android.content.Intent; @@ -373,29 +372,6 @@ public class NotificationEntryTest extends SysuiTestCase { } @Test - public void notificationDataEntry_testIsLastMessageFromReply_invalidData() { - Bundle bundle = new Bundle(); - bundle.putParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - new NotificationChannelGroup[]{}); - - Notification notification = new Notification.Builder(mContext, "test") - .addExtras(bundle) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("pkg") - .setOpPkg("pkg") - .setTag("tag") - .setNotification(notification) - .setUser(mContext.getUser()) - .setOverrideGroupKey("") - .build(); - entry.setHasSentReply(); - - assertFalse(entry.isLastMessageFromReply()); - } - - @Test public void notificationDataEntry_testIsLastMessageFromReply_invalidPerson_noCrash() { Person.Builder person = new Person.Builder() .setName("name") |