Merge "Show RemoteInput images in notification history."
This commit is contained in:
committed by
Android (Google) Code Review
commit
c4035ef38d
@@ -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.
|
||||
|
||||
90
core/java/android/app/RemoteInputHistoryItem.java
Normal file
90
core/java/android/app/RemoteInputHistoryItem.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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] -->
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -120,6 +122,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;
|
||||
|
||||
/**
|
||||
@@ -595,8 +599,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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -149,14 +151,31 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
|
||||
assertTrue(mRemoteInputManager.getEntriesKeptForRemoteInputActive().isEmpty());
|
||||
}
|
||||
|
||||
@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);
|
||||
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("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, 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(text, messages[1].getText());
|
||||
assertEquals(mimeType, messages[1].getMimeType());
|
||||
assertEquals(uri, messages[1].getUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user