diff options
author | Brad Fitzpatrick <bradfitz@android.com> | 2010-11-21 18:46:08 -0800 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@android.com> | 2010-11-23 12:44:08 -0800 |
commit | ce81f3a955a0e77e44e1f76c976905ec2a52c1d0 (patch) | |
tree | 4c6f95fbdc3e42937c2d2a18dbacafa35a47a856 /core/java/android | |
parent | b43d7589cf6201fc05f4c9d8b4a0c44d7cdba81e (diff) | |
download | frameworks_base-ce81f3a955a0e77e44e1f76c976905ec2a52c1d0.zip frameworks_base-ce81f3a955a0e77e44e1f76c976905ec2a52c1d0.tar.gz frameworks_base-ce81f3a955a0e77e44e1f76c976905ec2a52c1d0.tar.bz2 |
StrictMode.Span annotations for ScrollView.
Between the animation system, ListView, and this, we can now account
for the large majority of animations in-flight at any point and annotate
StrictMode violations accordingly.
Note that StrictMode.Span goes out of its way to not allocate memory
and is very light-weight, especially on user builds where it's a
no-op.
I've tested this with the LOG_V debugging in StrictMode and I think
I've gotten all the entry/exit cases of ScrollView's animations. At
least, I'm not able to get it out-of-sync at least, even with
orientation changes during scroll/fling, etc. It's possible I missed
a path, but that should show up as excessive false positives during
dropbox uploads if so.
Change-Id: I3b0545111a775d9fa8e171f2a190031f1b56c4c0
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/widget/ScrollView.java | 91 |
1 files changed, 70 insertions, 21 deletions
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 3faec55..900c9ec 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -24,6 +24,7 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.StrictMode; import android.util.AttributeSet; import android.view.FocusFinder; import android.view.KeyEvent; @@ -128,7 +129,16 @@ public class ScrollView extends FrameLayout { * drags/flings if multiple pointers are used. */ private int mActivePointerId = INVALID_POINTER; - + + /** + * The StrictMode "critical time span" objects to catch animation + * stutters. Non-null when a time-sensitive animation is + * in-flight. Must call finish() on them when done animating. + * These are no-ops on user builds. + */ + private StrictMode.Span mScrollStrictSpan = null; // aka "drag" + private StrictMode.Span mFlingStrictSpan = null; + /** * Sentinel value for no current active pointer. * Used by {@link #mActivePointerId}. @@ -437,6 +447,9 @@ public class ScrollView extends FrameLayout { if (yDiff > mTouchSlop) { mIsBeingDragged = true; mLastMotionY = y; + if (mScrollStrictSpan == null) { + mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll"); + } } break; } @@ -461,6 +474,9 @@ public class ScrollView extends FrameLayout { * being flinged. */ mIsBeingDragged = !mScroller.isFinished(); + if (mIsBeingDragged && mScrollStrictSpan == null) { + mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll"); + } break; } @@ -512,6 +528,10 @@ public class ScrollView extends FrameLayout { */ if (!mScroller.isFinished()) { mScroller.abortAnimation(); + if (mFlingStrictSpan != null) { + mFlingStrictSpan.finish(); + mFlingStrictSpan = null; + } } // Remember where the motion event started @@ -577,16 +597,7 @@ public class ScrollView extends FrameLayout { } mActivePointerId = INVALID_POINTER; - mIsBeingDragged = false; - - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - if (mEdgeGlowTop != null) { - mEdgeGlowTop.onRelease(); - mEdgeGlowBottom.onRelease(); - } + endDrag(); } break; case MotionEvent.ACTION_CANCEL: @@ -595,15 +606,7 @@ public class ScrollView extends FrameLayout { invalidate(); } mActivePointerId = INVALID_POINTER; - mIsBeingDragged = false; - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - if (mEdgeGlowTop != null) { - mEdgeGlowTop.onRelease(); - mEdgeGlowBottom.onRelease(); - } + endDrag(); } break; case MotionEvent.ACTION_POINTER_UP: @@ -1004,6 +1007,10 @@ public class ScrollView extends FrameLayout { } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); + if (mFlingStrictSpan != null) { + mFlingStrictSpan.finish(); + mFlingStrictSpan = null; + } } scrollBy(dx, dy); } @@ -1122,6 +1129,11 @@ public class ScrollView extends FrameLayout { // Keep on drawing until the animation has finished. postInvalidate(); + } else { + if (mFlingStrictSpan != null) { + mFlingStrictSpan.finish(); + mFlingStrictSpan = null; + } } } @@ -1296,6 +1308,20 @@ public class ScrollView extends FrameLayout { } @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + if (mScrollStrictSpan != null) { + mScrollStrictSpan.finish(); + mScrollStrictSpan = null; + } + if (mFlingStrictSpan != null) { + mFlingStrictSpan.finish(); + mFlingStrictSpan = null; + } + } + + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mIsLayoutDirty = false; @@ -1368,11 +1394,34 @@ public class ScrollView extends FrameLayout { mScrollViewMovedFocus = true; mScrollViewMovedFocus = false; } - + + if (mFlingStrictSpan == null) { + mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling"); + } + invalidate(); } } + private void endDrag() { + mIsBeingDragged = false; + + if (mVelocityTracker != null) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + + if (mEdgeGlowTop != null) { + mEdgeGlowTop.onRelease(); + mEdgeGlowBottom.onRelease(); + } + + if (mScrollStrictSpan != null) { + mScrollStrictSpan.finish(); + mScrollStrictSpan = null; + } + } + /** * {@inheritDoc} * |