Merge changes Ide3e8e94,I84e7c06e

* changes:
  Fixed flickering when swiping away last notification
  Fixed the order of notifications when Bubbles are present
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 5002f5c..3609835 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -17,6 +17,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 import java.util.Collection;
@@ -29,12 +30,13 @@
  * Keeps track of active bubbles.
  */
 @Singleton
-class BubbleData {
+public class BubbleData {
 
     private HashMap<String, Bubble> mBubbles = new HashMap<>();
 
+    @VisibleForTesting
     @Inject
-    BubbleData() {}
+    public BubbleData() {}
 
     /**
      * The set of bubbles.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index ee5ac7c..2e35f06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -22,8 +22,10 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 
 import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleData;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -74,6 +76,7 @@
      * possible.
      */
     private final boolean mAlwaysExpandNonGroupedNotification;
+    private final BubbleData mBubbleData;
 
     private NotificationPresenter mPresenter;
     private NotificationListContainer mListContainer;
@@ -85,7 +88,8 @@
             VisualStabilityManager visualStabilityManager,
             StatusBarStateController statusBarStateController,
             NotificationEntryManager notificationEntryManager,
-            Lazy<ShadeController> shadeController) {
+            Lazy<ShadeController> shadeController,
+            BubbleData bubbleData) {
         mLockscreenUserManager = notificationLockscreenUserManager;
         mGroupManager = groupManager;
         mVisualStabilityManager = visualStabilityManager;
@@ -95,6 +99,7 @@
         Resources res = context.getResources();
         mAlwaysExpandNonGroupedNotification =
                 res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
+        mBubbleData = bubbleData;
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
@@ -114,7 +119,8 @@
         final int N = activeNotifications.size();
         for (int i = 0; i < N; i++) {
             NotificationEntry ent = activeNotifications.get(i);
-            if (ent.isRowDismissed() || ent.isRowRemoved()) {
+            if (ent.isRowDismissed() || ent.isRowRemoved()
+                    || (mBubbleData.getBubble(ent.key) != null && !ent.showInShadeWhenBubble())) {
                 // we don't want to update removed notifications because they could
                 // temporarily become children if they were isolated before.
                 continue;
@@ -185,6 +191,11 @@
             if (v.getParent() == null) {
                 mVisualStabilityManager.notifyViewAddition(v);
                 mListContainer.addContainerView(v);
+            } else if (!mListContainer.containsView(v)) {
+                // the view is added somewhere else. Let's make sure
+                // the ordering works properly below, by excluding these
+                toShow.remove(v);
+                i--;
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index f771be0..212808d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -176,4 +176,12 @@
      * @param row The notification to bind.
      */
     default void bindRow(ExpandableNotificationRow row) {}
+
+    /**
+     * Does this list contain a given view. True by default is fine, since we only ask this if the
+     * view has a parent.
+     */
+    default boolean containsView(View v) {
+        return true;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index a54de5f..813faa9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -2482,7 +2482,8 @@
             int minBottomPosition = minTopPosition;
             if (section == lastSection) {
                 // We need to make sure the section goes all the way to the shelf
-                minBottomPosition = (int) (mShelf.getTranslationY() + mShelf.getIntrinsicHeight());
+                minBottomPosition = (int) (ViewState.getFinalTranslationY(mShelf)
+                        + mShelf.getIntrinsicHeight());
             }
             minTopPosition = section.updateBounds(minTopPosition, minBottomPosition,
                     shiftPulsingWithFirst);
@@ -3273,6 +3274,11 @@
     }
 
     @Override
+    public boolean containsView(View v) {
+        return v.getParent() == this;
+    }
+
+    @Override
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     public void applyExpandAnimationParams(ExpandAnimationParameters params) {
         mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 6b2e05b..2172a12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -37,6 +37,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.bubbles.BubbleData;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -97,7 +98,7 @@
         mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
                 mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
                 mock(StatusBarStateControllerImpl.class), mEntryManager,
-                () -> mShadeController);
+                () -> mShadeController, new BubbleData());
         Dependency.get(InitController.class).executePostInitTasks();
         mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
     }