When animating between states, animate the view width

Test: add media notification observe no flickery animation
Bug: 154137987
Change-Id: I909dd4427813b34426cc7d7fc08f298761f134bc
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 5a5cd6d..0b0bfc6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -36,6 +36,7 @@
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState;
 import android.service.media.MediaBrowserService;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -93,6 +94,7 @@
     private final Executor mForegroundExecutor;
     protected final Executor mBackgroundExecutor;
     private final ActivityStarter mActivityStarter;
+    private final LayoutAnimationHelper mLayoutAnimationHelper;
 
     private Context mContext;
     private MotionLayout mMediaNotifView;
@@ -109,6 +111,7 @@
     private String mKey;
     private int mAlbumArtSize;
     private int mAlbumArtRadius;
+    private int mViewWidth;
 
     public static final String MEDIA_PREFERENCES = "media_control_prefs";
     public static final String MEDIA_PREFERENCE_KEY = "browser_components";
@@ -176,6 +179,7 @@
         LayoutInflater inflater = LayoutInflater.from(mContext);
         mMediaNotifView = (MotionLayout) inflater.inflate(R.layout.qs_media_panel, parent, false);
         mBackground = mMediaNotifView.findViewById(R.id.media_background);
+        mLayoutAnimationHelper = new LayoutAnimationHelper(mMediaNotifView);
         mKeyFrames = mMediaNotifView.getDefinedTransitions().get(0).getKeyFrameList();
         mLocalMediaManager = routeManager;
         mForegroundExecutor = foregroundExecutor;
@@ -732,4 +736,32 @@
      * Called when a player can't be resumed to give it an opportunity to hide or remove itself
      */
     protected void removePlayer() { }
+
+    public void setDimension(int newWidth, int newHeight, boolean animate, long duration,
+            long startDelay) {
+        // Let's remeasure if our width changed. Our height is dependent on the expansion, so we
+        // won't animate if it changed
+        if (newWidth != mViewWidth) {
+            if (animate) {
+                mLayoutAnimationHelper.animatePendingSizeChange(duration, startDelay);
+            }
+            setViewWidth(newWidth);
+            mMediaNotifView.layout(0, 0, newWidth, mMediaNotifView.getMeasuredHeight());
+        }
+    }
+
+    protected void setViewWidth(int newWidth) {
+        ConstraintSet expandedSet = mMediaNotifView.getConstraintSet(R.id.expanded);
+        ConstraintSet collapsedSet = mMediaNotifView.getConstraintSet(R.id.collapsed);
+        collapsedSet.setGuidelineBegin(R.id.view_width, newWidth);
+        expandedSet.setGuidelineBegin(R.id.view_width, newWidth);
+        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
+        int widthSpec = View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
+                View.MeasureSpec.AT_MOST);
+        int heightSpec = View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
+                View.MeasureSpec.AT_MOST);
+        mMediaNotifView.setMinimumWidth(displayMetrics.widthPixels);
+        mMediaNotifView.measure(widthSpec, heightSpec);
+        mViewWidth = newWidth;
+    }
 }