diff options
9 files changed, 286 insertions, 54 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 6f63eea1163d..4315ae6614a0 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1004,6 +1004,31 @@ public class Notification implements Parcelable */ public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory"; + + /** + * {@link #extras} key: this is a remote input history which can include media messages + * in addition to text, as supplied to + * {@link Builder#setRemoteInputHistory(RemoteInputHistoryItem[])} or + * {@link Builder#setRemoteInputHistory(CharSequence[])}. + * + * SystemUI can populate this through + * {@link Builder#setRemoteInputHistory(RemoteInputHistoryItem[])} with the most recent inputs + * that have been sent through a {@link RemoteInput} of this Notification. These items can + * represent either media content (specified by a URI and a MIME type) or a text message + * (described by a CharSequence). + * + * To maintain compatibility, this can also be set by apps with + * {@link Builder#setRemoteInputHistory(CharSequence[])}, which will create a + * {@link RemoteInputHistoryItem} for each of the provided text-only messages. + * + * The extra with this key is of type {@link RemoteInputHistoryItem[]} and contains the most + * recent entry at the 0 index, the second most recent at the 1 index, etc. + * + * @see Builder#setRemoteInputHistory(RemoteInputHistoryItem[]) + * @hide + */ + public static final String EXTRA_REMOTE_INPUT_HISTORY_ITEMS = "android.remoteInputHistoryItems"; + /** * {@link #extras} key: boolean as supplied to * {@link Builder#setShowRemoteInputSpinner(boolean)}. @@ -3833,12 +3858,37 @@ public class Notification implements Parcelable if (text == null) { mN.extras.putCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY, null); } else { - final int N = Math.min(MAX_REPLY_HISTORY, text.length); - CharSequence[] safe = new CharSequence[N]; - for (int i = 0; i < N; i++) { + final int itemCount = Math.min(MAX_REPLY_HISTORY, text.length); + CharSequence[] safe = new CharSequence[itemCount]; + RemoteInputHistoryItem[] items = new RemoteInputHistoryItem[itemCount]; + for (int i = 0; i < itemCount; i++) { safe[i] = safeCharSequence(text[i]); + items[i] = new RemoteInputHistoryItem(text[i]); } mN.extras.putCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY, safe); + + // Also add these messages as structured history items. + mN.extras.putParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS, items); + } + return this; + } + + /** + * Set the remote input history, with support for embedding URIs and mime types for + * images and other media. + * @hide + */ + @NonNull + public Builder setRemoteInputHistory(RemoteInputHistoryItem[] items) { + if (items == null) { + mN.extras.putParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS, null); + } else { + final int itemCount = Math.min(MAX_REPLY_HISTORY, items.length); + RemoteInputHistoryItem[] history = new RemoteInputHistoryItem[itemCount]; + for (int i = 0; i < itemCount; i++) { + history[i] = items[i]; + } + mN.extras.putParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS, history); } return this; } @@ -5246,16 +5296,17 @@ public class Notification implements Parcelable big.setViewVisibility(R.id.actions_container, View.GONE); } - CharSequence[] replyText = mN.extras.getCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY); - if (validRemoteInput && replyText != null - && replyText.length > 0 && !TextUtils.isEmpty(replyText[0]) + RemoteInputHistoryItem[] replyText = (RemoteInputHistoryItem[]) + mN.extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + if (validRemoteInput && replyText != null && replyText.length > 0 + && !TextUtils.isEmpty(replyText[0].getText()) && p.maxRemoteInputHistory > 0) { boolean showSpinner = mN.extras.getBoolean(EXTRA_SHOW_REMOTE_INPUT_SPINNER); big.setViewVisibility(R.id.notification_material_reply_container, View.VISIBLE); big.setViewVisibility(R.id.notification_material_reply_text_1_container, View.VISIBLE); big.setTextViewText(R.id.notification_material_reply_text_1, - processTextSpans(replyText[0])); + processTextSpans(replyText[0].getText())); setTextViewColorSecondary(big, R.id.notification_material_reply_text_1, p); big.setViewVisibility(R.id.notification_material_reply_progress, showSpinner ? View.VISIBLE : View.GONE); @@ -5264,19 +5315,19 @@ public class Notification implements Parcelable ColorStateList.valueOf( isColorized(p) ? getPrimaryTextColor(p) : resolveContrastColor(p))); - if (replyText.length > 1 && !TextUtils.isEmpty(replyText[1]) + if (replyText.length > 1 && !TextUtils.isEmpty(replyText[1].getText()) && p.maxRemoteInputHistory > 1) { big.setViewVisibility(R.id.notification_material_reply_text_2, View.VISIBLE); big.setTextViewText(R.id.notification_material_reply_text_2, - processTextSpans(replyText[1])); + processTextSpans(replyText[1].getText())); setTextViewColorSecondary(big, R.id.notification_material_reply_text_2, p); - if (replyText.length > 2 && !TextUtils.isEmpty(replyText[2]) + if (replyText.length > 2 && !TextUtils.isEmpty(replyText[2].getText()) && p.maxRemoteInputHistory > 2) { big.setViewVisibility( R.id.notification_material_reply_text_3, View.VISIBLE); big.setTextViewText(R.id.notification_material_reply_text_3, - processTextSpans(replyText[2])); + processTextSpans(replyText[2].getText())); setTextViewColorSecondary(big, R.id.notification_material_reply_text_3, p); } } @@ -7517,7 +7568,7 @@ public class Notification implements Parcelable @Nullable private final Person mSender; /** True if this message was generated from the extra - * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY} + * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY_ITEMS} */ private final boolean mRemoteInputHistory; @@ -7569,7 +7620,7 @@ public class Notification implements Parcelable * Should be <code>null</code> for messages by the current user, in which case * the platform will insert the user set in {@code MessagingStyle(Person)}. * @param remoteInputHistory True if the messages was generated from the extra - * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY}. + * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY_ITEMS}. * <p> * The person provided should contain an Icon, set with * {@link Person.Builder#setIcon(Icon)} and also have a name provided @@ -7676,7 +7727,7 @@ public class Notification implements Parcelable /** * @return True if the message was generated from - * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY}. + * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY_ITEMS}. * @hide */ public boolean isRemoteInputHistory() { @@ -7906,8 +7957,8 @@ public class Notification implements Parcelable if (mBuilder.mActions.size() > 0) { maxRows--; } - CharSequence[] remoteInputHistory = mBuilder.mN.extras.getCharSequenceArray( - EXTRA_REMOTE_INPUT_HISTORY); + RemoteInputHistoryItem[] remoteInputHistory = (RemoteInputHistoryItem[]) + mBuilder.mN.extras.getParcelableArray(EXTRA_REMOTE_INPUT_HISTORY_ITEMS); if (remoteInputHistory != null && remoteInputHistory.length > NUMBER_OF_HISTORY_ALLOWED_UNTIL_REDUCTION) { // Let's remove some messages to make room for the remote input history. diff --git a/core/java/android/app/RemoteInputHistoryItem.java b/core/java/android/app/RemoteInputHistoryItem.java new file mode 100644 index 000000000000..091db3f142ae --- /dev/null +++ b/core/java/android/app/RemoteInputHistoryItem.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Stores historical input from a RemoteInput attached to a Notification. + * + * History items represent either a text message (specified by providing a CharSequence, + * or a media message (specified by providing a URI and a MIME type). Media messages must also + * include text to insert when the image cannot be loaded, ex. when URI read permission has not been + * granted correctly. + * + * @hide + */ +public class RemoteInputHistoryItem implements Parcelable { + private CharSequence mText; + private String mMimeType; + private Uri mUri; + + public RemoteInputHistoryItem(String mimeType, Uri uri, CharSequence backupText) { + this.mMimeType = mimeType; + this.mUri = uri; + this.mText = Notification.safeCharSequence(backupText); + } + + public RemoteInputHistoryItem(CharSequence text) { + this.mText = Notification.safeCharSequence(text); + } + + protected RemoteInputHistoryItem(Parcel in) { + mText = in.readCharSequence(); + mMimeType = in.readStringNoHelper(); + mUri = in.readParcelable(Uri.class.getClassLoader()); + } + + public static final Creator<RemoteInputHistoryItem> CREATOR = + new Creator<RemoteInputHistoryItem>() { + @Override + public RemoteInputHistoryItem createFromParcel(Parcel in) { + return new RemoteInputHistoryItem(in); + } + + @Override + public RemoteInputHistoryItem[] newArray(int size) { + return new RemoteInputHistoryItem[size]; + } + }; + + public CharSequence getText() { + return mText; + } + + public String getMimeType() { + return mMimeType; + } + + public Uri getUri() { + return mUri; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeCharSequence(mText); + dest.writeStringNoHelper(mMimeType); + dest.writeParcelable(mUri, flags); + } +} diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index 07d0d7d91997..f6089589a994 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.StyleRes; import android.app.Notification; import android.app.Person; +import android.app.RemoteInputHistoryItem; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -161,8 +162,9 @@ public class MessagingLayout extends FrameLayout implements ImageMessageConsumer if (headerText != null) { mConversationTitle = headerText.getText(); } - addRemoteInputHistoryToMessages(newMessages, - extras.getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY)); + RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[]) + extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + addRemoteInputHistoryToMessages(newMessages, history); boolean showSpinner = extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false); bind(newMessages, newHistoricMessages, showSpinner); @@ -175,14 +177,18 @@ public class MessagingLayout extends FrameLayout implements ImageMessageConsumer private void addRemoteInputHistoryToMessages( List<Notification.MessagingStyle.Message> newMessages, - CharSequence[] remoteInputHistory) { + RemoteInputHistoryItem[] remoteInputHistory) { if (remoteInputHistory == null || remoteInputHistory.length == 0) { return; } for (int i = remoteInputHistory.length - 1; i >= 0; i--) { - CharSequence message = remoteInputHistory[i]; - newMessages.add(new Notification.MessagingStyle.Message( - message, 0, (Person) null, true /* remoteHistory */)); + RemoteInputHistoryItem historyMessage = remoteInputHistory[i]; + Notification.MessagingStyle.Message message = new Notification.MessagingStyle.Message( + historyMessage.getText(), 0, (Person) null, true /* remoteHistory */); + if (historyMessage.getUri() != null) { + message.setData(historyMessage.getMimeType(), historyMessage.getUri()); + } + newMessages.add(message); } } diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 4f532b7b751d..201fbd95e876 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -194,6 +194,10 @@ <!-- Power menu item for taking a screenshot [CHAR LIMIT=20]--> <string name="global_action_screenshot">Screenshot</string> + <!-- text to show in place of RemoteInput images when they cannot be shown. + [CHAR LIMIT=50] --> + <string name="remote_input_image_insertion_text">Image inserted</string> + <!-- Notification ticker displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=30] --> <string name="screenshot_saving_ticker">Saving screenshot\u2026</string> <!-- Notification title displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=50] --> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 667e721ae37d..f3783c83a301 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -25,8 +25,10 @@ import android.app.KeyguardManager; import android.app.Notification; import android.app.PendingIntent; import android.app.RemoteInput; +import android.app.RemoteInputHistoryItem; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; @@ -345,7 +347,8 @@ public class NotificationRemoteInputManager implements Dumpable { }); mSmartReplyController.setCallback((entry, reply) -> { StatusBarNotification newSbn = - rebuildNotificationWithRemoteInput(entry, reply, true /* showSpinner */); + rebuildNotificationWithRemoteInput(entry, reply, true /* showSpinner */, + null /* mimeType */, null /* uri */); mEntryManager.updateNotification(newSbn, null /* ranking */); }); } @@ -527,28 +530,36 @@ public class NotificationRemoteInputManager implements Dumpable { StatusBarNotification rebuildNotificationForCanceledSmartReplies( NotificationEntry entry) { return rebuildNotificationWithRemoteInput(entry, null /* remoteInputTest */, - false /* showSpinner */); + false /* showSpinner */, null /* mimeType */, null /* uri */); } @VisibleForTesting StatusBarNotification rebuildNotificationWithRemoteInput(NotificationEntry entry, - CharSequence remoteInputText, boolean showSpinner) { + CharSequence remoteInputText, boolean showSpinner, String mimeType, Uri uri) { StatusBarNotification sbn = entry.getSbn(); Notification.Builder b = Notification.Builder .recoverBuilder(mContext, sbn.getNotification().clone()); - if (remoteInputText != null) { - CharSequence[] oldHistory = sbn.getNotification().extras - .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY); - CharSequence[] newHistory; - if (oldHistory == null) { - newHistory = new CharSequence[1]; + if (remoteInputText != null || uri != null) { + RemoteInputHistoryItem[] oldHistoryItems = (RemoteInputHistoryItem[]) + sbn.getNotification().extras.getParcelableArray( + Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + RemoteInputHistoryItem[] newHistoryItems; + + if (oldHistoryItems == null) { + newHistoryItems = new RemoteInputHistoryItem[1]; } else { - newHistory = new CharSequence[oldHistory.length + 1]; - System.arraycopy(oldHistory, 0, newHistory, 1, oldHistory.length); + newHistoryItems = new RemoteInputHistoryItem[oldHistoryItems.length + 1]; + System.arraycopy(oldHistoryItems, 0, newHistoryItems, 1, oldHistoryItems.length); } - newHistory[0] = String.valueOf(remoteInputText); - b.setRemoteInputHistory(newHistory); + RemoteInputHistoryItem newItem; + if (uri != null) { + newItem = new RemoteInputHistoryItem(mimeType, uri, remoteInputText); + } else { + newItem = new RemoteInputHistoryItem(remoteInputText); + } + newHistoryItems[0] = newItem; + b.setRemoteInputHistory(newHistoryItems); } b.setShowRemoteInputSpinner(showSpinner); b.setHideSmartReplies(true); @@ -631,8 +642,11 @@ public class NotificationRemoteInputManager implements Dumpable { if (TextUtils.isEmpty(remoteInputText)) { remoteInputText = entry.remoteInputTextWhenReset; } + String remoteInputMimeType = entry.remoteInputMimeType; + Uri remoteInputUri = entry.remoteInputUri; StatusBarNotification newSbn = rebuildNotificationWithRemoteInput(entry, - remoteInputText, false /* showSpinner */); + remoteInputText, false /* showSpinner */, remoteInputMimeType, + remoteInputUri); entry.onRemoteInputInserted(); if (newSbn == null) { 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 28e486df29b9..7478c3a05caf 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 @@ -37,8 +37,10 @@ import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; import android.app.NotificationManager.Policy; import android.app.Person; +import android.app.RemoteInputHistoryItem; import android.content.Context; import android.graphics.drawable.Icon; +import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.service.notification.NotificationListenerService.Ranking; @@ -119,6 +121,8 @@ public final class NotificationEntry extends ListEntry { public int targetSdk; private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET; public CharSequence remoteInputText; + public String remoteInputMimeType; + public Uri remoteInputUri; private Notification.BubbleMetadata mBubbleMetadata; /** @@ -600,8 +604,8 @@ public final class NotificationEntry extends ListEntry { return false; } Bundle extras = mSbn.getNotification().extras; - CharSequence[] replyTexts = extras.getCharSequenceArray( - Notification.EXTRA_REMOTE_INPUT_HISTORY); + RemoteInputHistoryItem[] replyTexts = (RemoteInputHistoryItem[]) extras.getParcelableArray( + Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); if (!ArrayUtils.isEmpty(replyTexts)) { return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java index a3e13053d169..fa4bc2aba21a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java @@ -80,7 +80,15 @@ public class NotificationInlineImageResolver implements ImageResolver { public Drawable loadImage(Uri uri) { Drawable result = null; try { - result = hasCache() ? mImageCache.get(uri) : resolveImage(uri); + if (hasCache()) { + // if the uri isn't currently cached, try caching it first + if (!mImageCache.hasEntry(uri)) { + mImageCache.preload((uri)); + } + result = mImageCache.get(uri); + } else { + result = resolveImage(uri); + } } catch (IOException | SecurityException ex) { Log.d(TAG, "loadImage: Can't load image from " + uri, ex); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index 307e3bcbaba5..408b3a619ff1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -161,6 +161,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); RemoteInput.addResultsToIntent(mRemoteInputs, fillInIntent, results); + + mEntry.remoteInputText = mEditText.getText(); + mEntry.remoteInputUri = null; + mEntry.remoteInputMimeType = null; + if (mEntry.editedSuggestionInfo == null) { RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_FREE_FORM_INPUT); } else { @@ -177,6 +182,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); RemoteInput.addDataResultToIntent(mRemoteInput, fillInIntent, results); + mEntry.remoteInputText = mContext.getString(R.string.remote_input_image_insertion_text); + mEntry.remoteInputMimeType = contentType; + mEntry.remoteInputUri = data; + return fillInIntent; } @@ -184,7 +193,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.setEnabled(false); mSendButton.setVisibility(INVISIBLE); mProgressBar.setVisibility(VISIBLE); - mEntry.remoteInputText = mEditText.getText(); mEntry.lastRemoteInputSent = SystemClock.elapsedRealtime(); mController.addSpinning(mEntry.getKey(), mToken); mController.removeRemoteInput(mEntry, mToken); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java index 64b10c816da7..1117646c482b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java @@ -10,7 +10,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; +import android.app.RemoteInputHistoryItem; import android.content.Context; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; @@ -150,13 +152,30 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { } @Test + public void testRebuildWithRemoteInput_noExistingInput_image() { + Uri uri = mock(Uri.class); + String mimeType = "image/jpeg"; + String text = "image inserted"; + StatusBarNotification newSbn = + mRemoteInputManager.rebuildNotificationWithRemoteInput( + mEntry, text, false, mimeType, uri); + RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() + .extras.getParcelableArray(Notification.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_noExistingInputNoSpinner() { StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false); - CharSequence[] messages = newSbn.getNotification().extras - .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY); + mRemoteInputManager.rebuildNotificationWithRemoteInput( + mEntry, "A Reply", false, null, null); + RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(1, messages.length); - assertEquals("A Reply", messages[0]); + assertEquals("A Reply", messages[0].getText()); assertFalse(newSbn.getNotification().extras .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false)); assertTrue(newSbn.getNotification().extras @@ -166,11 +185,12 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { @Test public void testRebuildWithRemoteInput_noExistingInputWithSpinner() { StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", true); - CharSequence[] messages = newSbn.getNotification().extras - .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY); + mRemoteInputManager.rebuildNotificationWithRemoteInput( + mEntry, "A Reply", true, null, null); + RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(1, messages.length); - assertEquals("A Reply", messages[0]); + assertEquals("A Reply", messages[0].getText()); assertTrue(newSbn.getNotification().extras .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false)); assertTrue(newSbn.getNotification().extras @@ -181,18 +201,45 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { public void testRebuildWithRemoteInput_withExistingInput() { // Setup a notification entry with 1 remote input. StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false); + mRemoteInputManager.rebuildNotificationWithRemoteInput( + mEntry, "A Reply", false, null, null); + NotificationEntry entry = new NotificationEntryBuilder() + .setSbn(newSbn) + .build(); + + // Try rebuilding to add another reply. + newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput( + entry, "Reply 2", true, null, null); + RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + assertEquals(2, messages.length); + assertEquals("Reply 2", messages[0].getText()); + assertEquals("A Reply", messages[1].getText()); + } + + @Test + public void testRebuildWithRemoteInput_withExistingInput_image() { + // Setup a notification entry with 1 remote input. + Uri uri = mock(Uri.class); + String mimeType = "image/jpeg"; + String text = "image inserted"; + StatusBarNotification newSbn = + mRemoteInputManager.rebuildNotificationWithRemoteInput( + mEntry, text, false, mimeType, uri); NotificationEntry entry = new NotificationEntryBuilder() .setSbn(newSbn) .build(); // Try rebuilding to add another reply. - newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput(entry, "Reply 2", true); - CharSequence[] messages = newSbn.getNotification().extras - .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY); + newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput( + entry, "Reply 2", true, null, null); + RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() + .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); assertEquals(2, messages.length); - assertEquals("Reply 2", messages[0]); - assertEquals("A Reply", messages[1]); + assertEquals("Reply 2", messages[0].getText()); + assertEquals(text, messages[1].getText()); + assertEquals(mimeType, messages[1].getMimeType()); + assertEquals(uri, messages[1].getUri()); } @Test |