diff options
4 files changed, 100 insertions, 8 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 1c5d28aaf27b..0e21517c3a60 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -127,6 +127,8 @@ public abstract class BaseStatusBar extends SystemUI implements SystemProperties.getBoolean("debug.enable_remote_input", true); public static final boolean ENABLE_CHILD_NOTIFICATIONS = SystemProperties.getBoolean("debug.child_notifs", true); + public static final boolean FORCE_REMOTE_INPUT_HISTORY = + SystemProperties.getBoolean("debug.force_remoteinput_history", false); protected static final int MSG_SHOW_RECENT_APPS = 1019; protected static final int MSG_HIDE_RECENT_APPS = 1020; @@ -182,6 +184,13 @@ public abstract class BaseStatusBar extends SystemUI implements protected boolean mVisible; protected ArraySet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new ArraySet<>(); + /** + * Notifications with keys in this set are not actually around anymore. We kept them around + * when they were canceled in response to a remote input interaction. This allows us to show + * what you replied and allows you to continue typing into it. + */ + protected ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>(); + // mScreenOnFromKeyguard && mVisible. private boolean mVisibleToUser; @@ -566,6 +575,7 @@ public abstract class BaseStatusBar extends SystemUI implements public void run() { processForRemoteInput(sbn.getNotification()); String key = sbn.getKey(); + mKeysKeptForRemoteInput.remove(key); boolean isUpdate = mNotificationData.get(key) != null; // In case we don't allow child notifications, we ignore children of // notifications that have a summary, since we're not going to show them @@ -904,7 +914,7 @@ public abstract class BaseStatusBar extends SystemUI implements } } - protected View bindVetoButtonClickListener(View row, StatusBarNotification n) { + protected View bindVetoButtonClickListener(View row, final StatusBarNotification n) { View vetoButton = row.findViewById(R.id.veto); final String _pkg = n.getPackageName(); final String _tag = n.getTag(); @@ -917,6 +927,11 @@ public abstract class BaseStatusBar extends SystemUI implements mContext.getString(R.string.accessibility_notification_dismissed)); try { mBarService.onNotificationClear(_pkg, _tag, _id, _userId); + if (FORCE_REMOTE_INPUT_HISTORY + && mKeysKeptForRemoteInput.contains(n.getKey())) { + removeNotification(n.getKey(), null); + mKeysKeptForRemoteInput.remove(n.getKey()); + } } catch (RemoteException ex) { // system process is dead if we're here. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java index d7e47c27dc71..5fea674f47b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java @@ -21,6 +21,8 @@ import com.android.systemui.statusbar.phone.StatusBarWindowManager; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.RemoteInputView; +import android.util.ArraySet; + import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -29,7 +31,8 @@ import java.util.ArrayList; */ public class RemoteInputController { - private final ArrayList<WeakReference<NotificationData.Entry>> mRemoteInputs = new ArrayList<>(); + private final ArrayList<WeakReference<NotificationData.Entry>> mOpen = new ArrayList<>(); + private final ArraySet<String> mSpinning = new ArraySet<>(); private final ArrayList<Callback> mCallbacks = new ArrayList<>(3); private final HeadsUpManager mHeadsUpManager; @@ -44,7 +47,7 @@ public class RemoteInputController { boolean found = pruneWeakThenRemoveAndContains( entry /* contains */, null /* remove */); if (!found) { - mRemoteInputs.add(new WeakReference<>(entry)); + mOpen.add(new WeakReference<>(entry)); } apply(entry); @@ -58,6 +61,18 @@ public class RemoteInputController { apply(entry); } + public void addSpinning(String key) { + mSpinning.add(key); + } + + public void removeSpinning(String key) { + mSpinning.remove(key); + } + + public boolean isSpinning(String key) { + return mSpinning.contains(key); + } + private void apply(NotificationData.Entry entry) { mHeadsUpManager.setRemoteInputActive(entry, isRemoteInputActive(entry)); boolean remoteInputActive = isRemoteInputActive(); @@ -79,7 +94,7 @@ public class RemoteInputController { */ public boolean isRemoteInputActive() { pruneWeakThenRemoveAndContains(null /* contains */, null /* remove */); - return !mRemoteInputs.isEmpty(); + return !mOpen.isEmpty(); } /** @@ -91,10 +106,10 @@ public class RemoteInputController { private boolean pruneWeakThenRemoveAndContains( NotificationData.Entry contains, NotificationData.Entry remove) { boolean found = false; - for (int i = mRemoteInputs.size() - 1; i >= 0; i--) { - NotificationData.Entry item = mRemoteInputs.get(i).get(); + for (int i = mOpen.size() - 1; i >= 0; i--) { + NotificationData.Entry item = mOpen.get(i).get(); if (item == null || item == remove) { - mRemoteInputs.remove(i); + mOpen.remove(i); } else if (item == contains) { found = true; } @@ -108,7 +123,16 @@ public class RemoteInputController { mCallbacks.add(callback); } + public void remoteInputSent(NotificationData.Entry entry) { + int N = mCallbacks.size(); + for (int i = 0; i < N; i++) { + mCallbacks.get(i).onRemoteInputSent(entry); + } + } + public interface Callback { - void onRemoteInputActive(boolean active); + default void onRemoteInputActive(boolean active) {} + + default void onRemoteInputSent(NotificationData.Entry entry) {} } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index bb77c5be7002..d32cb8bb123c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1110,6 +1110,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStatusBarKeyguardViewManager); mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); mRemoteInputController.addCallback(mStatusBarKeyguardViewManager); + + if (FORCE_REMOTE_INPUT_HISTORY) { + mRemoteInputController.addCallback(new RemoteInputController.Callback() { + @Override + public void onRemoteInputSent(Entry entry) { + if (mKeysKeptForRemoteInput.contains(entry.key)) { + removeNotification(entry.key, null); + } + } + }); + } + mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback(); mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController); } @@ -1378,6 +1390,42 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, clearCurrentMediaNotification(); updateMediaMetaData(true, true); } + if (FORCE_REMOTE_INPUT_HISTORY && mRemoteInputController.isSpinning(key)) { + Entry entry = mNotificationData.get(key); + StatusBarNotification sbn = entry.notification; + + Notification.Builder b = Notification.Builder + .recoverBuilder(mContext, sbn.getNotification().clone()); + CharSequence[] oldHistory = sbn.getNotification().extras + .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY); + CharSequence[] newHistory; + if (oldHistory == null) { + newHistory = new CharSequence[1]; + } else { + newHistory = new CharSequence[oldHistory.length + 1]; + for (int i = 0; i < oldHistory.length; i++) { + newHistory[i + 1] = oldHistory[i]; + } + } + newHistory[0] = String.valueOf(entry.remoteInputText); + b.setRemoteInputHistory(newHistory); + + Notification newNotification = b.build(); + + // Undo any compatibility view inflation + newNotification.contentView = sbn.getNotification().contentView; + newNotification.bigContentView = sbn.getNotification().bigContentView; + newNotification.headsUpContentView = sbn.getNotification().headsUpContentView; + + StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(), + sbn.getOpPkg(), + sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(), + 0, newNotification, sbn.getUser(), sbn.getPostTime()); + + updateNotification(newSbn, null); + mKeysKeptForRemoteInput.add(entry.key); + return; + } if (deferRemoval) { mLatestRankingMap = ranking; mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key)); 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 1f4ef4a25f7f..557f166dc1a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -121,8 +121,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.setEnabled(false); mSendButton.setVisibility(INVISIBLE); mProgressBar.setVisibility(VISIBLE); + mEntry.remoteInputText = mEditText.getText(); + mController.addSpinning(mEntry.key); mController.removeRemoteInput(mEntry); mEditText.mShowImeOnInputConnection = false; + mController.remoteInputSent(mEntry); try { mPendingIntent.send(mContext, 0, fillInIntent); @@ -177,6 +180,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene return; } mController.removeRemoteInput(mEntry); + mController.removeSpinning(mEntry.key); } public void setPendingIntent(PendingIntent pendingIntent) { @@ -213,6 +217,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.setEnabled(true); mSendButton.setVisibility(VISIBLE); mProgressBar.setVisibility(INVISIBLE); + mController.removeSpinning(mEntry.key); updateSendButton(); onDefocus(); } |