summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2012-05-23 16:08:53 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2012-05-23 16:08:53 -0700
commit425f126a0f2284423f4ccea0b00fbd5ea670a6c9 (patch)
treecfe6851e3803c68895f0ed0c14974ce9f6217b03 /core
parent762932396aecab31a89f64399df9d44cc177e3df (diff)
parenta865d7d7d3612d99e3b1407793610056c7df163c (diff)
downloadframeworks_base-425f126a0f2284423f4ccea0b00fbd5ea670a6c9.zip
frameworks_base-425f126a0f2284423f4ccea0b00fbd5ea670a6c9.tar.gz
frameworks_base-425f126a0f2284423f4ccea0b00fbd5ea670a6c9.tar.bz2
am a865d7d7: am df3633b3: Merge "Make it harder for apps to mess up ViewGroup\'s internal state Bug #6421288" into jb-dev
* commit 'a865d7d7d3612d99e3b1407793610056c7df163c': Make it harder for apps to mess up ViewGroup's internal state Bug #6421288
Diffstat (limited to 'core')
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/view/ViewGroup.java52
-rw-r--r--core/java/android/view/animation/Animation.java79
3 files changed, 118 insertions, 15 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 483560c..706ad59 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12697,6 +12697,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();
}
@@ -12710,6 +12711,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)) ==
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ab42d57..1aec7c8 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -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
*
@@ -3168,6 +3172,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;
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index d92ebcd..85d77cb 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -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();
}
}
@@ -341,6 +348,38 @@ public abstract class Animation implements Cloneable {
}
/**
+ * 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();
}
}
@@ -868,7 +900,28 @@ 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