OSDN Git Service

Add option to force remote input history
authorAdrian Roos <roosa@google.com>
Wed, 30 Mar 2016 23:43:58 +0000 (16:43 -0700)
committerAdrian Roos <roosa@google.com>
Wed, 30 Mar 2016 23:46:34 +0000 (16:46 -0700)
Bug: 27851227
Change-Id: Iced5d24d6cc0894ce7c7e9565722d0ef016a50a5

packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java

index 2d2a08a..51cc0a0 100644 (file)
@@ -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.
index d7e47c2..5fea674 100644 (file)
@@ -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) {}
     }
 }
index e84d8fc..bfe8446 100644 (file)
@@ -48,7 +48,6 @@ import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
@@ -132,7 +131,6 @@ import com.android.systemui.statusbar.DismissView;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
@@ -1106,6 +1104,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);
     }
@@ -1374,6 +1384,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));
index 3a0336b..ec8e3ff 100644 (file)
@@ -119,8 +119,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);
@@ -175,6 +178,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
             return;
         }
         mController.removeRemoteInput(mEntry);
+        mController.removeSpinning(mEntry.key);
     }
 
     public void setPendingIntent(PendingIntent pendingIntent) {
@@ -211,6 +215,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
         mEditText.setEnabled(true);
         mSendButton.setVisibility(VISIBLE);
         mProgressBar.setVisibility(INVISIBLE);
+        mController.removeSpinning(mEntry.key);
         updateSendButton();
         onDefocus();
     }