Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 711e62a8 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #3225529: AlertDialogs are squishing their content views

ViewRoot is now smarter about measuring WRAP/WRAP windows.

Change-Id: I690fc78ddbe252d7c8070edb8e7352aec6c67ce9
parent 974ab305
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -61579,6 +61579,19 @@
<parameter name="that" type="android.content.res.Configuration">
</parameter>
</method>
<method name="isLayoutSizeAtLeast"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="size" type="int">
</parameter>
</method>
<method name="needNewResources"
 return="boolean"
 abstract="false"
+16 −0
Original line number Diff line number Diff line
@@ -91,6 +91,22 @@ public final class Configuration implements Parcelable, Comparable<Configuration
     */
    public int screenLayout;
    
    /**
     * Check if the Configuration's current {@link #screenLayout} is at
     * least the given size.
     *
     * @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
     * {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
     * {@link #SCREENLAYOUT_SIZE_XLARGE}.
     * @return Returns true if the current screen layout size is at least
     * the given size.
     */
    public boolean isLayoutSizeAtLeast(int size) {
        int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
        if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
        return size >= cur;
    }

    public static final int TOUCHSCREEN_UNDEFINED = 0;
    public static final int TOUCHSCREEN_NOTOUCH = 1;
    public static final int TOUCHSCREEN_STYLUS = 2;
+63 −12
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.InputQueue.FinishedCallback;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
@@ -87,7 +88,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
    /** @noinspection PointlessBooleanExpression*/
    private static final boolean DEBUG_DRAW = false || LOCAL_LOGV;
    private static final boolean DEBUG_LAYOUT = false || LOCAL_LOGV;
    private static final boolean DEBUG_INPUT = true || LOCAL_LOGV;
    private static final boolean DEBUG_DIALOG = false || LOCAL_LOGV;
    private static final boolean DEBUG_INPUT_RESIZE = false || LOCAL_LOGV;
    private static final boolean DEBUG_ORIENTATION = false || LOCAL_LOGV;
    private static final boolean DEBUG_TRACKBALL = false || LOCAL_LOGV;
@@ -125,6 +126,8 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn

    final int[] mTmpLocation = new int[2];

    final TypedValue mTmpValue = new TypedValue();
    
    final InputMethodCallback mInputMethodCallback;
    final SparseArray<Object> mPendingEvents = new SparseArray<Object>();
    int mPendingEventSeq = 0;
@@ -405,7 +408,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
                }
                mPendingContentInsets.set(mAttachInfo.mContentInsets);
                mPendingVisibleInsets.set(0, 0, 0, 0);
                if (Config.LOGV) Log.v(TAG, "Added window " + mWindow);
                if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow);
                if (res < WindowManagerImpl.ADD_OKAY) {
                    mView = null;
                    mAttachInfo.mRootView = null;
@@ -639,7 +642,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn

        mTraversalScheduled = false;
        mWillDrawSoon = true;
        boolean windowResizesToFitContent = false;
        boolean windowSizeMayChange = false;
        boolean fullRedrawNeeded = mFullRedrawNeeded;
        boolean newSurface = false;
        boolean surfaceChanged = false;
@@ -696,7 +699,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
                        "View " + host + " resized to: " + frame);
                fullRedrawNeeded = true;
                mLayoutRequested = true;
                windowResizesToFitContent = true;
                windowSizeMayChange = true;
            }
        }

@@ -722,6 +725,8 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
            // enqueued an action after being detached
            getRunQueue().executeActions(attachInfo.mHandler);

            final Resources res = mView.getContext().getResources();

            if (mFirst) {
                host.fitSystemWindows(mAttachInfo.mContentInsets);
                // make sure touch mode code executes by setting cached value
@@ -743,23 +748,69 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
                }
                if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
                        || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                    windowResizesToFitContent = true;
                    windowSizeMayChange = true;

                    DisplayMetrics packageMetrics =
                        mView.getContext().getResources().getDisplayMetrics();
                    DisplayMetrics packageMetrics = res.getDisplayMetrics();
                    desiredWindowWidth = packageMetrics.widthPixels;
                    desiredWindowHeight = packageMetrics.heightPixels;
                }
            }

            childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
            childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);

            // Ask host how big it wants to be
            if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(TAG,
                    "Measuring " + host + " in display " + desiredWindowWidth
                    + "x" + desiredWindowHeight + "...");

            boolean goodMeasure = false;
            if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
                    || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                // On large screens, we don't want to allow dialogs to just
                // stretch to fill the entire width of the screen to display
                // one line of text.  First try doing the layout at a smaller
                // size to see if it will fit.
                final DisplayMetrics packageMetrics = res.getDisplayMetrics();
                res.getValue(com.android.internal.R.dimen.config_prefDialogWidth, mTmpValue, true);
                int baseSize = 0;
                if (mTmpValue.type == TypedValue.TYPE_DIMENSION) {
                    baseSize = (int)mTmpValue.getDimension(packageMetrics);
                }
                if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": baseSize=" + baseSize);
                if (desiredWindowWidth > baseSize) {
                    int maxHeight = (desiredWindowHeight*2)/3;
                    childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
                    childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
                    host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
                    if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": measured ("
                            + host.getWidth() + "," + host.getHeight() + ")");
                    // Note: for now we are not taking into account height, since we
                    // can't distinguish between places where it would be useful to
                    // increase the width (text) vs. where it would not (a list).
                    // Maybe we can just try the next size up, and see if that reduces
                    // the height?
                    if (host.getWidth() <= baseSize /*&& host.getHeight() <= maxHeight*/) {
                        Log.v(TAG, "Good!");
                        goodMeasure = true;
                    } else {
                        // Didn't fit in that size... try expanding a bit.
                        baseSize = (baseSize+desiredWindowWidth)/2;
                        if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": next baseSize="
                                + baseSize);
                        host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
                        if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": measured ("
                                + host.getWidth() + "," + host.getHeight() + ")");
                        if (host.getWidth() <= baseSize /*&& host.getHeight() <= maxHeight*/) {
                            if (DEBUG_DIALOG) Log.v(TAG, "Good!");
                            goodMeasure = true;
                        }
                    }
                }
            }

            if (!goodMeasure) {
                childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
                childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
                host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }

            if (DBG) {
                System.out.println("======================================");
@@ -812,7 +863,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
            }
        }

        boolean windowShouldResize = mLayoutRequested && windowResizesToFitContent
        boolean windowShouldResize = mLayoutRequested && windowSizeMayChange
            && ((mWidth != host.mMeasuredWidth || mHeight != host.mMeasuredHeight)
                || (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT &&
                        frame.width() < desiredWindowWidth && frame.width() != mWidth)
+1 −3
Original line number Diff line number Diff line
@@ -29,9 +29,7 @@
    android:paddingLeft="3dip"
    android:paddingRight="1dip"
    android:majorWeightMin="0.45"
    android:minorWeightMin="0.72"
    android:majorWeightMax="0.45"
    android:minorWeightMax="0.72">
    android:minorWeightMin="0.72">

    <LinearLayout android:id="@+id/topPanel"
        android:layout_width="match_parent"
+1 −3
Original line number Diff line number Diff line
@@ -28,9 +28,7 @@
    android:paddingLeft="3dip"
    android:paddingRight="1dip"
    android:majorWeightMin="0.45"
    android:minorWeightMin="0.72"
    android:majorWeightMax="0.45"
    android:minorWeightMax="0.72">
    android:minorWeightMin="0.72">

    <LinearLayout android:id="@+id/topPanel"
        android:layout_width="match_parent"
Loading