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

Commit 7a583e7b authored by Alan Viverette's avatar Alan Viverette
Browse files

Allow null layers in LayerDrawable

Bug: 20098214
Change-Id: I80285ddda7101ab7403048d38f9c40af6b692a1a
parent 05ce40e1
Loading
Loading
Loading
Loading
+166 −61
Original line number Diff line number Diff line
@@ -297,7 +297,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            }

            final Drawable d = layer.mDrawable;
            if (d.canApplyTheme()) {
            if (d != null && d.canApplyTheme()) {
                d.applyTheme(t);

                // Update cached mask of child changing configurations.
@@ -881,7 +881,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.draw(canvas);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.draw(canvas);
            }
        }
    }

@@ -946,23 +949,28 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
     */
    @Override
    public void getOutline(@NonNull Outline outline) {
        final LayerState state = mLayerState;
        final ChildDrawable[] children = state.mChildren;
        final int N = state.mNum;
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            children[i].mDrawable.getOutline(outline);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.getOutline(outline);
                if (!outline.isEmpty()) {
                    return;
                }
            }
        }
    }

    @Override
    public void setHotspot(float x, float y) {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setHotspot(x, y);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setHotspot(x, y);
            }
        }
    }

@@ -971,7 +979,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setHotspotBounds(left, top, right, bottom);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setHotspotBounds(left, top, right, bottom);
            }
        }

        if (mHotspotBounds == null) {
@@ -996,7 +1007,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setVisible(visible, restart);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setVisible(visible, restart);
            }
        }

        return changed;
@@ -1007,17 +1021,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setDither(dither);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setDither(dither);
            }
        }
    }

    @Override
    public boolean getDither() {
        final ChildDrawable[] array = mLayerState.mChildren;
        if (mLayerState.mNum > 0) {
            // All layers should have the same dither set on them - just return
            // the first one
            return array[0].mDrawable.getDither();
        final Drawable dr = getFirstNonNullDrawable();
        if (dr != null) {
            return dr.getDither();
        } else {
            return super.getDither();
        }
@@ -1028,17 +1043,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setAlpha(alpha);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setAlpha(alpha);
            }
        }
    }

    @Override
    public int getAlpha() {
        final ChildDrawable[] array = mLayerState.mChildren;
        if (mLayerState.mNum > 0) {
            // All layers should have the same alpha set on them - just return
            // the first one
            return array[0].mDrawable.getAlpha();
        final Drawable dr = getFirstNonNullDrawable();
        if (dr != null) {
            return dr.getAlpha();
        } else {
            return super.getAlpha();
        }
@@ -1049,7 +1065,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setColorFilter(colorFilter);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setColorFilter(colorFilter);
            }
        }
    }

@@ -1058,7 +1077,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setTintList(tint);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setTintList(tint);
            }
        }
    }

@@ -1067,10 +1089,25 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setTintMode(tintMode);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setTintMode(tintMode);
            }
        }
    }

    private Drawable getFirstNonNullDrawable() {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                return dr;
            }
        }
        return null;
    }

    /**
     * Sets the opacity of this drawable directly, instead of collecting the
     * states from the layers
@@ -1101,7 +1138,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.setAutoMirrored(mirrored);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.setAutoMirrored(mirrored);
            }
        }
    }

@@ -1122,9 +1162,9 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            final ChildDrawable r = array[i];
            if (r.mDrawable.isStateful() && r.mDrawable.setState(state)) {
                refreshChildPadding(i, r);
            final Drawable dr = array[i].mDrawable;
            if (dr != null && dr.isStateful() && dr.setState(state)) {
                refreshChildPadding(i, array[i]);
                changed = true;
            }
        }
@@ -1143,9 +1183,9 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            final ChildDrawable r = array[i];
            if (r.mDrawable.setLevel(level)) {
                refreshChildPadding(i, r);
            final Drawable dr = array[i].mDrawable;
            if (dr != null && dr.setLevel(level)) {
                refreshChildPadding(i, array[i]);
                changed = true;
            }
        }
@@ -1176,6 +1216,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        for (int i = 0; i < N; i++) {
            final ChildDrawable r = array[i];
            final Drawable d = r.mDrawable;
            if (d == null) {
                continue;
            }

            final Rect container = mTmpContainer;
            container.set(d.getBounds());

@@ -1257,6 +1301,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            final ChildDrawable r = array[i];
            if (r.mDrawable == null) {
                continue;
            }

            final int minWidth = r.mWidth < 0 ? r.mDrawable.getIntrinsicWidth() : r.mWidth;
            final int w = minWidth + r.mInsetL + r.mInsetR + padL + padR;
            if (w > width) {
@@ -1283,6 +1331,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            final ChildDrawable r = array[i];
            if (r.mDrawable == null) {
                continue;
            }

            final int minHeight = r.mHeight < 0 ? r.mDrawable.getIntrinsicHeight() : r.mHeight;
            final int h = minHeight + r.mInsetT + r.mInsetB + padT + padB;
            if (h > height) {
@@ -1304,6 +1356,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
     * @return true if the child's padding has changed
     */
    private boolean refreshChildPadding(int i, ChildDrawable r) {
        if (r.mDrawable != null) {
            final Rect rect = mTmpRect;
            r.mDrawable.getPadding(rect);
            if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
@@ -1314,6 +1367,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
                mPaddingB[i] = rect.bottom;
                return true;
            }
        }
        return false;
    }

@@ -1348,7 +1402,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            final ChildDrawable[] array = mLayerState.mChildren;
            final int N = mLayerState.mNum;
            for (int i = 0; i < N; i++) {
                array[i].mDrawable.mutate();
                final Drawable dr = array[i].mDrawable;
                if (dr != null) {
                    dr.mutate();
                }
            }
            mMutated = true;
        }
@@ -1360,10 +1417,14 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
     */
    public void clearMutated() {
        super.clearMutated();

        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            array[i].mDrawable.clearMutated();
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                dr.clearMutated();
            }
        }
        mMutated = false;
    }
@@ -1371,11 +1432,16 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
    @Override
    public boolean onLayoutDirectionChange(int layoutDirection) {
        boolean changed = false;

        final ChildDrawable[] array = mLayerState.mChildren;
        final int N = mLayerState.mNum;
        for (int i = 0; i < N; i++) {
            changed |= array[i].mDrawable.setLayoutDirection(layoutDirection);
            final Drawable dr = array[i].mDrawable;
            if (dr != null) {
                changed |= dr.setLayoutDirection(layoutDirection);
            }
        }

        updateLayerBounds(getBounds());
        return changed;
    }
@@ -1396,15 +1462,24 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
        }

        ChildDrawable(ChildDrawable orig, LayerDrawable owner, Resources res) {
            final Drawable dr = orig.mDrawable;
            final Drawable clone;
            if (dr != null) {
                final ConstantState cs = dr.getConstantState();
                if (res != null) {
                mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
                    clone = cs.newDrawable(res);
                } else {
                    clone = cs.newDrawable();
                }
                clone.setCallback(owner);
                clone.setLayoutDirection(dr.getLayoutDirection());
                clone.setBounds(dr.getBounds());
                clone.setLevel(dr.getLevel());
            } else {
                mDrawable = orig.mDrawable.getConstantState().newDrawable();
                clone = null;
            }
            mDrawable.setCallback(owner);
            mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
            mDrawable.setBounds(orig.mDrawable.getBounds());
            mDrawable.setLevel(orig.mDrawable.getLevel());

            mDrawable = clone;
            mThemeAttrs = orig.mThemeAttrs;
            mInsetL = orig.mInsetL;
            mInsetT = orig.mInsetT;
@@ -1417,6 +1492,11 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            mGravity = orig.mGravity;
            mId = orig.mId;
        }

        public boolean canApplyTheme() {
            return mThemeAttrs != null
                    || (mDrawable != null && mDrawable.canApplyTheme());
        }
    }

    static class LayerState extends ConstantState {
@@ -1476,7 +1556,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            final int N = mNum;
            for (int i = 0; i < N; i++) {
                final ChildDrawable layer = array[i];
                if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) {
                if (layer.canApplyTheme()) {
                    return true;
                }
            }
@@ -1507,9 +1587,29 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {

            final ChildDrawable[] array = mChildren;
            final int N = mNum;
            int op = N > 0 ? array[0].mDrawable.getOpacity() : PixelFormat.TRANSPARENT;
            for (int i = 1; i < N; i++) {
                op = Drawable.resolveOpacity(op, array[i].mDrawable.getOpacity());

            // Seek to the first non-null drawable.
            int firstIndex = -1;
            for (int i = 0; i < N; i++) {
                if (array[i].mDrawable != null) {
                    firstIndex = i;
                    break;
                }
            }

            int op;
            if (firstIndex >= 0) {
                op = array[firstIndex].mDrawable.getOpacity();
            } else {
                op = PixelFormat.TRANSPARENT;
            }

            // Merge all remaining non-null drawables.
            for (int i = firstIndex + 1; i < N; i++) {
                final Drawable dr = array[i].mDrawable;
                if (dr != null) {
                    op = Drawable.resolveOpacity(op, dr.getOpacity());
                }
            }

            mOpacity = op;
@@ -1526,7 +1626,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            final int N = mNum;
            boolean isStateful = false;
            for (int i = 0; i < N; i++) {
                if (array[i].mDrawable.isStateful()) {
                final Drawable dr = array[i].mDrawable;
                if (dr != null && dr.isStateful()) {
                    isStateful = true;
                    break;
                }
@@ -1541,7 +1642,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            final ChildDrawable[] array = mChildren;
            final int N = mNum;
            for (int i = 0; i < N; i++) {
                if (array[i].mDrawable.getConstantState() == null) {
                final Drawable dr = array[i].mDrawable;
                if (dr != null && dr.getConstantState() == null) {
                    return false;
                }
            }
@@ -1561,11 +1663,14 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
            final int N = mNum;
            int pixelCount = 0;
            for (int i = 0; i < N; i++) {
                final ConstantState state = array[i].mDrawable.getConstantState();
                final Drawable dr = array[i].mDrawable;
                if (dr != null) {
                    final ConstantState state = dr.getConstantState();
                    if (state != null) {
                        pixelCount += state.addAtlasableBitmaps(atlasList);
                    }
                }
            }
            return pixelCount;
        }
    }