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

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

Fix for reveal animated drawables

Includes fixes for RevealDrawable clipping, touch feedback constant
state, and action bar background display lists.

BUG: 13065159
Change-Id: Ie4bf03f59da69047e18a8fe9233c3d24b0160576
parent 5314b3d5
Loading
Loading
Loading
Loading
+48 −28
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ActionMode;
@@ -50,7 +51,8 @@ public class ActionBarContainer extends FrameLayout {
    public ActionBarContainer(Context context, AttributeSet attrs) {
        super(context, attrs);

        setBackgroundDrawable(null);
        // Set a transparent background so that we project appropriately.
        setBackground(new ActionBarBackgroundDrawable());

        TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.ActionBar);
@@ -241,24 +243,6 @@ public class ActionBarContainer extends FrameLayout {
        return mTabContainer;
    }

    @Override
    public void onDraw(Canvas canvas) {
        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }

        if (mIsSplit) {
            if (mSplitBackground != null) mSplitBackground.draw(canvas);
        } else {
            if (mBackground != null) {
                mBackground.draw(canvas);
            }
            if (mStackedBackground != null && mIsStacked) {
                mStackedBackground.draw(canvas);
            }
        }
    }

    @Override
    public ActionMode startActionModeForChild(View child, ActionMode.Callback callback) {
        // No starting an action mode for an action bar child! (Where would it go?)
@@ -290,12 +274,13 @@ public class ActionBarContainer extends FrameLayout {
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE;
        final View tabContainer = mTabContainer;
        final boolean hasTabs = tabContainer != null && tabContainer.getVisibility() != GONE;

        if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
        if (tabContainer != null && tabContainer.getVisibility() != GONE) {
            final int containerHeight = getMeasuredHeight();
            final int tabHeight = mTabContainer.getMeasuredHeight();
            mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
            final int tabHeight = tabContainer.getMeasuredHeight();
            tabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
        }

        boolean needsInvalidate = false;
@@ -306,13 +291,15 @@ public class ActionBarContainer extends FrameLayout {
            }
        } else {
            if (mBackground != null) {
                mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
                        mActionBarView.getRight(), mActionBarView.getBottom());
                final ActionBarView actionBarView = mActionBarView;
                mBackground.setBounds(actionBarView.getLeft(), actionBarView.getTop(),
                        actionBarView.getRight(), actionBarView.getBottom());
                needsInvalidate = true;
            }
            if ((mIsStacked = hasTabs && mStackedBackground != null)) {
                mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(),
                        mTabContainer.getRight(), mTabContainer.getBottom());
            mIsStacked = hasTabs;
            if (hasTabs && mStackedBackground != null) {
                mStackedBackground.setBounds(tabContainer.getLeft(), tabContainer.getTop(),
                        tabContainer.getRight(), tabContainer.getBottom());
                needsInvalidate = true;
            }
        }
@@ -321,4 +308,37 @@ public class ActionBarContainer extends FrameLayout {
            invalidate();
        }
    }

    /**
     * Dummy drawable so that we don't break background display lists and
     * projection surfaces.
     */
    private class ActionBarBackgroundDrawable extends Drawable {
        @Override
        public void draw(Canvas canvas) {
            if (mIsSplit) {
                if (mSplitBackground != null) mSplitBackground.draw(canvas);
            } else {
                if (mBackground != null) {
                    mBackground.draw(canvas);
                }
                if (mStackedBackground != null && mIsStacked) {
                    mStackedBackground.draw(canvas);
                }
            }
        }

        @Override
        public void setAlpha(int alpha) {
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
        }

        @Override
        public int getOpacity() {
            return 0;
        }
    }
}
+10 −8
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.graphics.drawable;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
@@ -233,16 +232,14 @@ public class RevealDrawable extends LayerDrawable {

        getDrawable(0).draw(canvas);

        final Rect bounds = getBounds();
        final ArrayList<Ripple> activeRipples = mActiveRipples;
        if (layerCount == 1 || activeRipples == null || activeRipples.isEmpty()) {
        if (layerCount == 1 || bounds.isEmpty() || activeRipples == null
                || activeRipples.isEmpty()) {
            // Nothing to reveal, we're done here.
            return;
        }

        final Rect bounds = getBounds();
        final int width = bounds.width();
        final int height = bounds.height();

        if (mRipplePaint == null) {
            mRipplePaint = new Paint();
            mRipplePaint.setAntiAlias(true);
@@ -260,7 +257,11 @@ public class RevealDrawable extends LayerDrawable {
                n--;
            } else {
                if (layerSaveCount < 0) {
                    layerSaveCount = canvas.saveLayer(0, 0, width, height, null, 0);
                    layerSaveCount = canvas.saveLayer(
                            bounds.left, bounds.top, bounds.right, bounds.bottom, null, 0);
                    // Ripples must be clipped to bounds, otherwise SRC_IN will
                    // miss them and we'll get artifacts.
                    canvas.clipRect(bounds);
                }

                needsMask |= ripple.draw(canvas, mRipplePaint);
@@ -279,7 +280,8 @@ public class RevealDrawable extends LayerDrawable {

                // TODO: When Drawable.setXfermode() is supported by all drawables,
                // we won't need an extra layer.
                canvas.saveLayer(0, 0, width, height, mMaskingPaint, 0);
                canvas.saveLayer(
                        bounds.left, bounds.top, bounds.right, bounds.bottom, mMaskingPaint, 0);
                getDrawable(1).draw(canvas);
            }

+10 −5
Original line number Diff line number Diff line
@@ -338,11 +338,16 @@ public class TouchFeedbackDrawable extends Drawable {
        return dirtyBounds;
    }

    private static class TouchFeedbackState extends ConstantState {
        private ColorStateList mColorStateList;
        private Xfermode mXfermode;
        private int mTargetDensity;
        private boolean mProjected;
    @Override
    public ConstantState getConstantState() {
        return mState;
    }

    static class TouchFeedbackState extends ConstantState {
        ColorStateList mColorStateList;
        Xfermode mXfermode;
        int mTargetDensity;
        boolean mProjected;

        public TouchFeedbackState(TouchFeedbackState orig) {
            if (orig != null) {