Fix crash & positioning of notif-based bubbles

We don't need to be adding the row view until the bubble is expanded so
I moved the code to where we actually show the view & added a check to
remove it from the parent (notif stack scroll layout) if it's attached.

Fixes an issue where the expanded state could be in the wrong position.
This was because the y calculation for the expanded state happened
before it's new height was calculated so it could be incorrect.

Test: manual (1) - Have some notif based bubbles
                 - Dismiss the bubble stack
                 - Receive an update for one of those bubbles
                 => SysUI doesn't crash
             (2) - Have 2 bubbles
                 - Tap on the stack
                 - Tap on the 2nd bubble
                 => Expanded state should be positioned correctly

Fixes: 127383589
Fixes: 126550620
Change-Id: Ic2c20d81a2997665810eb9240b28da90f1a9fad5
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 603b3b9..4addbb5 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -49,6 +49,7 @@
 import android.util.Log;
 import android.util.StatsLog;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
 import android.widget.ImageButton;
@@ -316,8 +317,25 @@
     /**
      * Lets activity view know it should be shown / populated.
      */
-    public void populateActivityView() {
-        mActivityView.setCallback(mStateCallback);
+    public void populateExpandedView() {
+        if (usingActivityView()) {
+            mActivityView.setCallback(mStateCallback);
+        } else {
+            // We're using notification template
+            ViewGroup parent = (ViewGroup) mNotifRow.getParent();
+            if (parent == this) {
+                // Already added
+                return;
+            } else if (parent != null) {
+                // Still in the shade... remove it
+                parent.removeView(mNotifRow);
+            }
+            if (mShowOnTop) {
+                addView(mNotifRow);
+            } else {
+                addView(mNotifRow, mUseFooter ? 0 : 1);
+            }
+        }
     }
 
     /**
@@ -376,14 +394,8 @@
         } else {
             // Hide activity view if we had it previously
             mActivityView.setVisibility(GONE);
-
-            // Use notification view
             mNotifRow = mEntry.getRow();
-            if (mShowOnTop) {
-                addView(mNotifRow);
-            } else {
-                addView(mNotifRow, mUseFooter ? 0 : 1);
-            }
+
         }
         updateView();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 8235d8d..ade5647 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -766,7 +766,7 @@
         mExpandedViewContainer.removeAllViews();
         if (mExpandedBubble != null && mIsExpanded) {
             mExpandedViewContainer.addView(mExpandedBubble.expandedView);
-            mExpandedBubble.expandedView.populateActivityView();
+            mExpandedBubble.expandedView.populateExpandedView();
             mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
         }
     }
@@ -776,8 +776,12 @@
 
         mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
         if (mIsExpanded) {
+            // First update the view so that it calculates a new height (ensuring the y position
+            // calculation is correct)
+            mExpandedBubble.expandedView.updateView();
             final float y = getYPositionForExpandedView();
             mExpandedViewContainer.setTranslationY(y);
+            // Then update the view so that ActivityView knows we translated
             mExpandedBubble.expandedView.updateView();
         }