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

Commit 9a04856d authored by Fabrice Di Meglio's avatar Fabrice Di Meglio
Browse files

Other improvements for bug #6427629 Clean up layout direction APIs

- hide isLayoutRtl() from public API

- canResolveXXX() is now smarter: use recursion to get its returned value

- in ViewGroup, if resolution cannot be done then dont ask resolution for
its children

- in ViewGroup, addViewInner() needs to ask to resolve the child. This is
needed for example by ListView which is using the same measurespec before
and after its childs being attached.

It also take care of the general case where a measure pass is done when not
attached to a parent (and thus asking for resolution that will "fail" if we
are using IHNERIT) and never done again. That would lead to never do a
resolution.

- some code refactoring

Change-Id: I120dd2fef7397944f5ba8deff0686b108dc827d2
parent 0b171158
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -25038,7 +25038,6 @@ package android.view {
    method public boolean isInEditMode();
    method public boolean isInTouchMode();
    method public boolean isLayoutRequested();
    method public boolean isLayoutRtl();
    method public boolean isLongClickable();
    method public boolean isOpaque();
    method protected boolean isPaddingOffsetRequired();
+80 −58
Original line number Diff line number Diff line
@@ -5859,6 +5859,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * layout attribute and/or the inherited value from the parent
     *
     * @return true if the layout is right-to-left.
     *
     * @hide
     */
    @ViewDebug.ExportedProperty(category = "layout")
    public boolean isLayoutRtl() {
@@ -11591,9 +11593,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
     * that the parent directionality can and will be resolved before its children.
     *
     * @return true if resolution has been done, false otherwise.
     *
     * @hide
     */
    public void resolveLayoutDirection() {
    public boolean resolveLayoutDirection() {
        // Clear any previous layout direction resolution
        mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
@@ -11604,15 +11608,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                case LAYOUT_DIRECTION_INHERIT:
                    // We cannot resolve yet. LTR is by default and let the resolution happen again
                    // later to get the correct resolved value
                    if (!canResolveLayoutDirection()) return;
                    if (!canResolveLayoutDirection()) return false;
                    ViewGroup viewGroup = ((ViewGroup) mParent);
                    View parent = ((View) mParent);
                    // Parent has not yet resolved, LTR is still the default
                    if (!parent.isLayoutDirectionResolved()) return false;
                    // We cannot resolve yet on the parent too. LTR is by default and let the
                    // resolution happen again later
                    if (!viewGroup.canResolveLayoutDirection()) return;
                    if (viewGroup.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
                    if (parent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
                        mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
                    }
                    break;
@@ -11632,6 +11634,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        // Set to resolved
        mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
        return true;
    }
    /**
@@ -11642,10 +11645,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @hide
     */
    public boolean canResolveLayoutDirection() {
        switch ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >>
                PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) {
        switch (getRawLayoutDirection()) {
            case LAYOUT_DIRECTION_INHERIT:
                return (mParent != null) && (mParent instanceof ViewGroup);
                return (mParent != null) && (mParent instanceof ViewGroup) &&
                       ((ViewGroup) mParent).canResolveLayoutDirection();
            default:
                return true;
        }
@@ -16622,9 +16625,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * Resolve the text direction.
     *
     * @return true if resolution has been done, false otherwise.
     *
     * @hide
     */
    public void resolveTextDirection() {
    public boolean resolveTextDirection() {
        // Reset any previous text direction resolution
        mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
@@ -16633,11 +16638,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            final int textDirection = getRawTextDirection();
            switch(textDirection) {
                case TEXT_DIRECTION_INHERIT:
                    if (canResolveTextDirection()) {
                        ViewGroup viewGroup = ((ViewGroup) mParent);
                    if (!canResolveTextDirection()) {
                        // We cannot do the resolution if there is no parent, so use the default one
                        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
                        // Resolution will need to happen again later
                        return false;
                    }
                    View parent = ((View) mParent);
                    // Parent has not yet resolved, so we still return the default
                    if (!parent.isTextDirectionResolved()) {
                        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
                        // Resolution will need to happen again later
                        return false;
                    }
                    // Set current resolved direction to the same value as the parent's one
                        final int parentResolvedDirection = viewGroup.getTextDirection();
                    final int parentResolvedDirection = parent.getTextDirection();
                    switch (parentResolvedDirection) {
                        case TEXT_DIRECTION_FIRST_STRONG:
                        case TEXT_DIRECTION_ANY_RTL:
@@ -16651,12 +16668,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                            // Default resolved direction is "first strong" heuristic
                            mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
                    }
                    } else {
                        // We cannot do the resolution if there is no parent, so use the default one
                        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
                        // Resolution will need to happen again later
                        return;
                    }
                    break;
                case TEXT_DIRECTION_FIRST_STRONG:
                case TEXT_DIRECTION_ANY_RTL:
@@ -16677,6 +16688,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        // Set to resolved
        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
        return true;
    }
    /**
@@ -16687,7 +16699,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private boolean canResolveTextDirection() {
        switch (getRawTextDirection()) {
            case TEXT_DIRECTION_INHERIT:
                return (mParent != null) && (mParent instanceof ViewGroup);
                return (mParent != null) && (mParent instanceof View) &&
                       ((View) mParent).canResolveTextDirection();
            default:
                return true;
        }
@@ -16817,9 +16830,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * Resolve the text alignment.
     *
     * @return true if resolution has been done, false otherwise.
     *
     * @hide
     */
    public void resolveTextAlignment() {
    public boolean resolveTextAlignment() {
        // Reset any previous text alignment resolution
        mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
@@ -16829,10 +16844,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            switch (textAlignment) {
                case TEXT_ALIGNMENT_INHERIT:
                    // Check if we can resolve the text alignment
                    if (canResolveTextAlignment() && mParent instanceof View) {
                        View view = (View) mParent;
                    if (!canResolveTextAlignment()) {
                        // We cannot do the resolution if there is no parent so use the default
                        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
                        // Resolution will need to happen again later
                        return false;
                    }
                    View parent = (View) mParent;
                        final int parentResolvedTextAlignment = view.getTextAlignment();
                    // Parent has not yet resolved, so we still return the default
                    if (!parent.isTextAlignmentResolved()) {
                        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
                        // Resolution will need to happen again later
                        return false;
                    }
                    final int parentResolvedTextAlignment = parent.getTextAlignment();
                    switch (parentResolvedTextAlignment) {
                        case TEXT_ALIGNMENT_GRAVITY:
                        case TEXT_ALIGNMENT_TEXT_START:
@@ -16849,13 +16876,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                            // Use default resolved text alignment
                            mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
                    }
                    }
                    else {
                        // We cannot do the resolution if there is no parent so use the default
                        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
                        // Resolution will need to happen again later
                        return;
                    }
                    break;
                case TEXT_ALIGNMENT_GRAVITY:
                case TEXT_ALIGNMENT_TEXT_START:
@@ -16877,6 +16897,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        // Set the resolved
        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
        return true;
    }
    /**
@@ -16887,7 +16908,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private boolean canResolveTextAlignment() {
        switch (getRawTextAlignment()) {
            case TEXT_DIRECTION_INHERIT:
                return (mParent != null);
                return (mParent != null) && (mParent instanceof View) &&
                       ((View) mParent).canResolveTextAlignment();
            default:
                return true;
        }
+35 −24
Original line number Diff line number Diff line
@@ -3382,6 +3382,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            ai.mKeepScreenOn = lastKeepOn;
        }

        if (child.isLayoutDirectionInherited()) {
            child.resetResolvedLayoutDirection();
            child.resolveRtlPropertiesIfNeeded();
        }

        onViewAdded(child);

        if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) {
@@ -5256,9 +5261,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * @hide
     */
    @Override
    public void resolveLayoutDirection() {
        super.resolveLayoutDirection();

    public boolean resolveLayoutDirection() {
        final boolean result = super.resolveLayoutDirection();
        if (result) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
@@ -5267,14 +5272,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                }
            }
        }
        return result;
    }

    /**
     * @hide
     */
    @Override
    public void resolveTextDirection() {
        super.resolveTextDirection();

    public boolean resolveTextDirection() {
        final boolean result = super.resolveTextDirection();
        if (result) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
@@ -5283,14 +5290,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                }
            }
        }
        return result;
    }

    /**
     * @hide
     */
    @Override
    public void resolveTextAlignment() {
        super.resolveTextAlignment();

    public boolean resolveTextAlignment() {
        final boolean result = super.resolveTextAlignment();
        if (result) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
@@ -5299,6 +5308,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                }
            }
        }
        return result;
    }

    /**
     * @hide