Fix janky swiping with RemoteInputViews

Change-Id: Ie0f525b886c41fdd0f3ef7cc7efb525ed08f3560
Fixes: 28885122
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index b4ce9cd..a80ce98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -684,8 +684,13 @@
         return mRemoved;
     }
 
-    public void setRemoved(boolean removed) {
-        mRemoved = removed;
+    public void setRemoved() {
+        mRemoved = true;
+
+        mPrivateLayout.setRemoved();
+        if (mChildrenContainer != null) {
+            mChildrenContainer.setRemoved();
+        }
     }
 
     public NotificationChildrenContainer getChildrenContainer() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 5a8d4b3..bda4c0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -1041,4 +1041,13 @@
     public HybridNotificationView getSingleLineView() {
         return mSingleLineView;
     }
+
+    public void setRemoved() {
+        if (mExpandedRemoteInput != null) {
+            mExpandedRemoteInput.setRemoved();
+        }
+        if (mHeadsUpRemoteInput != null) {
+            mHeadsUpRemoteInput.setRemoved();
+        }
+    }
 }
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 e3ce1e2..5cde2ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1508,7 +1508,7 @@
         }
         Entry entry = mNotificationData.get(key);
         if (entry != null && entry.row != null) {
-            entry.row.setRemoved(true);
+            entry.row.setRemoved();
         }
         // Let's remove the children if this was a summary
         handleGroupSummaryRemoved(key, ranking);
@@ -1556,7 +1556,7 @@
                 toRemove.get(i).setKeepInParent(true);
                 // we need to set this state earlier as otherwise we might generate some weird
                 // animations
-                toRemove.get(i).setRemoved(true);
+                toRemove.get(i).setRemoved();
             }
             for (int i = 0; i < toRemove.size(); i++) {
                 removeNotification(toRemove.get(i).getStatusBarNotification().getKey(), ranking);
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 095265a..2f522f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -73,6 +73,7 @@
 
     private ScrollContainer mScrollContainer;
     private View mScrollContainerChild;
+    private boolean mRemoved;
 
     public RemoteInputView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -171,7 +172,12 @@
     public void onDefocus() {
         mController.removeRemoteInput(mEntry);
         mEntry.remoteInputText = mEditText.getText();
-        setVisibility(INVISIBLE);
+
+        // During removal, we get reattached and lose focus. Not hiding in that
+        // case to prevent flicker.
+        if (!mRemoved) {
+            setVisibility(INVISIBLE);
+        }
         MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE,
                 mEntry.notification.getPackageName());
     }
@@ -347,6 +353,10 @@
         return mPendingIntent;
     }
 
+    public void setRemoved() {
+        mRemoved = true;
+    }
+
     /**
      * An EditText that changes appearance based on whether it's focusable and becomes
      * un-focusable whenever the user navigates away from it or it becomes invisible.
@@ -416,6 +426,15 @@
         }
 
         @Override
+        public boolean onCheckIsTextEditor() {
+            // Stop being editable while we're being removed. During removal, we get reattached,
+            // and editable views get their spellchecking state re-evaluated which is too costly
+            // during the removal animation.
+            boolean flyingOut = mRemoteInputView != null && mRemoteInputView.mRemoved;
+            return !flyingOut && super.onCheckIsTextEditor();
+        }
+
+        @Override
         public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
             final InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index e919d5c..a5adac1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -685,4 +685,12 @@
         mHybridGroupManager.setOverflowNumberColor(mOverflowNumber,
                 mNotificationParent.getNotificationColor());
     }
+
+    public void setRemoved() {
+        int childCount = mChildren.size();
+        for (int i = 0; i < childCount; i++) {
+            ExpandableNotificationRow child = mChildren.get(i);
+            child.setRemoved();
+        }
+    }
 }