Fixed measuring and layouting of the more card and expandableviews.

Change-Id: I2848b39c6498ce9ad197ed7bad8423c74b372419
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index dc3d92a..724b6a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -45,7 +45,6 @@
             = new PathInterpolator(0.6f, 0, 0.5f, 1);
     private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
             = new PathInterpolator(0, 0, 0.5f, 1);
-    private final int mMaxNotificationHeight;
 
     private boolean mDimmed;
 
@@ -81,8 +80,6 @@
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
         mLinearOutSlowInInterpolator =
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
-        mMaxNotificationHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
         setClipChildren(false);
         setClipToPadding(false);
     }
@@ -296,27 +293,6 @@
     }
 
     @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int newHeightSpec = MeasureSpec.makeMeasureSpec(mMaxNotificationHeight,
-                MeasureSpec.AT_MOST);
-        int maxChildHeight = 0;
-        int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = getChildAt(i);
-            if (child != mBackgroundDimmed && child != mBackgroundNormal) {
-                child.measure(widthMeasureSpec, newHeightSpec);
-                int childHeight = child.getMeasuredHeight();
-                maxChildHeight = Math.max(maxChildHeight, childHeight);
-            }
-        }
-        newHeightSpec = MeasureSpec.makeMeasureSpec(maxChildHeight, MeasureSpec.EXACTLY);
-        mBackgroundDimmed.measure(widthMeasureSpec, newHeightSpec);
-        mBackgroundNormal.measure(widthMeasureSpec, newHeightSpec);
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        setMeasuredDimension(width, maxChildHeight);
-    }
-
-    @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         setPivotX(getWidth() / 2);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 8f92a4c..84005d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -258,11 +258,4 @@
     public void notifyContentUpdated() {
         mPrivateLayout.notifyContentUpdated();
     }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int newHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
-        mVetoButton.measure(widthMeasureSpec, newHeightSpec);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 5cb1b78..0d3116f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -21,34 +21,74 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import com.android.systemui.R;
+
+import java.util.ArrayList;
 
 /**
  * An abstract view for expandable views.
  */
-public abstract class ExpandableView extends ViewGroup {
+public abstract class ExpandableView extends FrameLayout {
+
+    private final int mMaxNotificationHeight;
 
     private OnHeightChangedListener mOnHeightChangedListener;
     protected int mActualHeight;
     protected int mClipTopAmount;
     private boolean mActualHeightInitialized;
+    private ArrayList<View> mMatchParentViews = new ArrayList<View>();
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mMaxNotificationHeight = getResources().getDimensionPixelSize(
+                R.dimen.notification_max_height);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int ownMaxHeight = mMaxNotificationHeight;
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
+        boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
+        if (hasFixedHeight || isHeightLimited) {
+            int size = MeasureSpec.getSize(heightMeasureSpec);
+            ownMaxHeight = Math.min(ownMaxHeight, size);
+        }
+        int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
+        int maxChildHeight = 0;
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            int childHeightSpec = newHeightSpec;
+            ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
+            if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) {
+                if (layoutParams.height >= 0) {
+                    // An actual height is set
+                    childHeightSpec = layoutParams.height > ownMaxHeight
+                        ? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
+                        : MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
+                }
+                child.measure(widthMeasureSpec, childHeightSpec);
+                int childHeight = child.getMeasuredHeight();
+                maxChildHeight = Math.max(maxChildHeight, childHeight);
+            } else {
+                mMatchParentViews.add(child);
+            }
+        }
+        int ownHeight = hasFixedHeight ? ownMaxHeight : maxChildHeight;
+        newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
+        for (View child : mMatchParentViews) {
+            child.measure(widthMeasureSpec, newHeightSpec);
+        }
+        mMatchParentViews.clear();
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        setMeasuredDimension(width, ownHeight);
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            int height = child.getMeasuredHeight();
-            int width = child.getMeasuredWidth();
-            int center = getWidth() / 2;
-            int childLeft = center - width / 2;
-            child.layout(childLeft,
-                    0,
-                    childLeft + width,
-                    height);
-        }
+        super.onLayout(changed, left, top, right, bottom);
         if (!mActualHeightInitialized && mActualHeight == 0) {
             mActualHeight = getInitialHeight();
         }