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

Commit 393a52c9 authored by Romain Guy's avatar Romain Guy
Browse files

Make it harder for apps to mess up ViewGroup's internal state

Bug #6421288

Change-Id: I8c2c597f45391d3c1ae40c8341a68bb25d8ad4d9
parent 956f28ed
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -12725,6 +12725,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        if (!initialized) {
            a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
            a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
            if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
            onAnimationStart();
        }
@@ -12738,6 +12739,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        } else {
            invalidationTransform = parent.mChildTransformation;
        }
        if (more) {
            if (!a.willChangeBounds()) {
                if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) ==
+50 −2
Original line number Diff line number Diff line
@@ -3154,8 +3154,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    }

    /**
     * Adds a child view. If no layout parameters are already set on the child, the
     * default parameters for this ViewGroup are set on the child.
     * <p>Adds a child view. If no layout parameters are already set on the child, the
     * default parameters for this ViewGroup are set on the child.</p>
     * 
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param child the child view to add
     *
@@ -3169,6 +3173,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * Adds a child view. If no layout parameters are already set on the child, the
     * default parameters for this ViewGroup are set on the child.
     * 
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param child the child view to add
     * @param index the position at which to add the child
     *
@@ -3189,6 +3197,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * Adds a child view with this ViewGroup's default layout parameters and the
     * specified width and height.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param child the child view to add
     */
    public void addView(View child, int width, int height) {
@@ -3201,6 +3213,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    /**
     * Adds a child view with the specified layout parameters.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param child the child view to add
     * @param params the layout parameters to set on the child
     */
@@ -3211,6 +3227,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    /**
     * Adds a child view with the specified layout parameters.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param child the child view to add
     * @param index the position at which to add the child
     * @param params the layout parameters to set on the child
@@ -3528,6 +3548,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager

    /**
     * {@inheritDoc}
     * 
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     */
    public void removeView(View view) {
        removeViewInternal(view);
@@ -3539,6 +3563,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * Removes a view during layout. This is useful if in your onLayout() method,
     * you need to remove more views.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     * 
     * @param view the view to remove from the group
     */
    public void removeViewInLayout(View view) {
@@ -3549,6 +3577,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * Removes a range of views during layout. This is useful if in your onLayout() method,
     * you need to remove more views.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param start the index of the first view to remove from the group
     * @param count the number of views to remove from the group
     */
@@ -3559,6 +3591,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    /**
     * Removes the view at the specified position in the group.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     * 
     * @param index the position in the group of the view to remove
     */
    public void removeViewAt(int index) {
@@ -3570,6 +3606,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    /**
     * Removes the specified range of views from the group.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     *
     * @param start the first position in the group of the range of views to remove
     * @param count the number of views to remove
     */
@@ -3715,6 +3755,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    /**
     * Call this method to remove all child views from the
     * ViewGroup.
     * 
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     */
    public void removeAllViews() {
        removeAllViewsInLayout();
@@ -3730,6 +3774,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * that can currently fit inside the object on screen. Do not call
     * this method unless you are extending ViewGroup and understand the
     * view measuring and layout pipeline.
     *
     * <p><strong>Note:</strong> do not invoke this method from
     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
     */
    public void removeAllViewsInLayout() {
        final int count = mChildrenCount;
+66 −13
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.RectF;
import android.os.Handler;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -207,6 +208,11 @@ public abstract class Animation implements Cloneable {

    private final CloseGuard guard = CloseGuard.get();

    private Handler mListenerHandler;
    private Runnable mOnStart;
    private Runnable mOnRepeat;
    private Runnable mOnEnd;

    /**
     * Creates a new animation with a duration of 0ms, the default interpolator, with
     * fillBefore set to true and fillAfter set to false
@@ -275,6 +281,7 @@ public abstract class Animation implements Cloneable {
        mRepeated = 0;
        mMore = true;
        mOneMoreTime = true;
        mListenerHandler = null;
    }

    /**
@@ -290,7 +297,7 @@ public abstract class Animation implements Cloneable {
     */
    public void cancel() {
        if (mStarted && !mEnded) {
            if (mListener != null) mListener.onAnimationEnd(this);
            fireAnimationEnd();
            mEnded = true;
            guard.close();
        }
@@ -306,7 +313,7 @@ public abstract class Animation implements Cloneable {
        if (mStarted && !mEnded) {
            mEnded = true;
            guard.close();
            if (mListener != null) mListener.onAnimationEnd(this);
            fireAnimationEnd();
        }
    }

@@ -340,6 +347,38 @@ public abstract class Animation implements Cloneable {
        mInitialized = true;
    }

    /**
     * Sets the handler used to invoke listeners.
     * 
     * @hide
     */
    public void setListenerHandler(Handler handler) {
        if (mListenerHandler == null) {
            mOnStart = new Runnable() {
                public void run() {
                    if (mListener != null) {
                        mListener.onAnimationStart(Animation.this);
                    }
                }
            };
            mOnRepeat = new Runnable() {
                public void run() {
                    if (mListener != null) {
                        mListener.onAnimationRepeat(Animation.this);
                    }
                }
            };
            mOnEnd = new Runnable() {
                public void run() {
                    if (mListener != null) {
                        mListener.onAnimationEnd(Animation.this);
                    }
                }
            };
        }
        mListenerHandler = handler;
    }

    /**
     * Sets the acceleration curve for this animation. The interpolator is loaded as
     * a resource from the specified context.
@@ -792,7 +831,6 @@ public abstract class Animation implements Cloneable {
     * @return True if the animation is still running
     */
    public boolean getTransformation(long currentTime, Transformation outTransformation) {

        if (mStartTime == -1) {
            mStartTime = currentTime;
        }
@@ -815,9 +853,7 @@ public abstract class Animation implements Cloneable {

        if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) {
            if (!mStarted) {
                if (mListener != null) {
                    mListener.onAnimationStart(this);
                }
                fireAnimationStart();
                mStarted = true;
                if (USE_CLOSEGUARD) {
                    guard.open("cancel or detach or getTransformation");
@@ -839,9 +875,7 @@ public abstract class Animation implements Cloneable {
                if (!mEnded) {
                    mEnded = true;
                    guard.close();
                    if (mListener != null) {
                        mListener.onAnimationEnd(this);
                    }
                    fireAnimationEnd();
                }
            } else {
                if (mRepeatCount > 0) {
@@ -855,9 +889,7 @@ public abstract class Animation implements Cloneable {
                mStartTime = -1;
                mMore = true;

                if (mListener != null) {
                    mListener.onAnimationRepeat(this);
                }
                fireAnimationRepeat();
            }
        }

@@ -869,6 +901,27 @@ public abstract class Animation implements Cloneable {
        return mMore;
    }

    private void fireAnimationStart() {
        if (mListener != null) {
            if (mListenerHandler == null) mListener.onAnimationStart(this);
            else mListenerHandler.postAtFrontOfQueue(mOnStart);
        }
    }

    private void fireAnimationRepeat() {
        if (mListener != null) {
            if (mListenerHandler == null) mListener.onAnimationRepeat(this);
            else mListenerHandler.postAtFrontOfQueue(mOnRepeat);
        }
    }

    private void fireAnimationEnd() {
        if (mListener != null) {
            if (mListenerHandler == null) mListener.onAnimationEnd(this);
            else mListenerHandler.postAtFrontOfQueue(mOnEnd);
        }
    }

    /**
     * Gets the transformation to apply at a specified point in time. Implementations of this
     * method should always replace the specified Transformation or document they are doing