diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/Notification.java | 83 | ||||
| -rw-r--r-- | core/java/android/app/RemoteInputHistoryItem.java | 90 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/MessagingLayout.java | 18 |
3 files changed, 169 insertions, 22 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 3c4e861d55f8..1af275fedd74 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); } } |
