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

Commit 9477229f authored by Alan Viverette's avatar Alan Viverette Committed by Android (Google) Code Review
Browse files

Merge "Smooth progress bar animations"

parents 7d92c474 a64ed3bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -40972,6 +40972,7 @@ package android.widget {
    method public void setInterpolator(android.view.animation.Interpolator);
    method public void setInterpolator(android.view.animation.Interpolator);
    method public synchronized void setMax(int);
    method public synchronized void setMax(int);
    method public synchronized void setProgress(int);
    method public synchronized void setProgress(int);
    method public void setProgress(int, boolean);
    method public void setProgressBackgroundTintList(android.content.res.ColorStateList);
    method public void setProgressBackgroundTintList(android.content.res.ColorStateList);
    method public void setProgressBackgroundTintMode(android.graphics.PorterDuff.Mode);
    method public void setProgressBackgroundTintMode(android.graphics.PorterDuff.Mode);
    method public void setProgressDrawable(android.graphics.drawable.Drawable);
    method public void setProgressDrawable(android.graphics.drawable.Drawable);
+1 −0
Original line number Original line Diff line number Diff line
@@ -43580,6 +43580,7 @@ package android.widget {
    method public void setInterpolator(android.view.animation.Interpolator);
    method public void setInterpolator(android.view.animation.Interpolator);
    method public synchronized void setMax(int);
    method public synchronized void setMax(int);
    method public synchronized void setProgress(int);
    method public synchronized void setProgress(int);
    method public void setProgress(int, boolean);
    method public void setProgressBackgroundTintList(android.content.res.ColorStateList);
    method public void setProgressBackgroundTintList(android.content.res.ColorStateList);
    method public void setProgressBackgroundTintMode(android.graphics.PorterDuff.Mode);
    method public void setProgressBackgroundTintMode(android.graphics.PorterDuff.Mode);
    method public void setProgressDrawable(android.graphics.drawable.Drawable);
    method public void setProgressDrawable(android.graphics.drawable.Drawable);
+14 −13
Original line number Original line Diff line number Diff line
@@ -385,9 +385,10 @@ public abstract class AbsSeekBar extends ProgressBar {
    }
    }


    @Override
    @Override
    void onProgressRefresh(float scale, boolean fromUser, int progress) {
    void onVisualProgressChanged(int id, float scale) {
        super.onProgressRefresh(scale, fromUser, progress);
        super.onVisualProgressChanged(id, scale);


        if (id == R.id.progress) {
            final Drawable thumb = mThumb;
            final Drawable thumb = mThumb;
            if (thumb != null) {
            if (thumb != null) {
                setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
                setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
@@ -398,6 +399,7 @@ public abstract class AbsSeekBar extends ProgressBar {
                invalidate();
                invalidate();
            }
            }
        }
        }
    }


    @Override
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
@@ -709,8 +711,7 @@ public abstract class AbsSeekBar extends ProgressBar {
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    increment = isLayoutRtl() ? -increment : increment;
                    increment = isLayoutRtl() ? -increment : increment;


                    // Let progress bar handle clamping values.
                    if (setProgressInternal(getProgress() + increment, true, true)) {
                    if (setProgress(getProgress() + increment, true)) {
                        onKeyChange();
                        onKeyChange();
                        return true;
                        return true;
                    }
                    }
@@ -764,7 +765,7 @@ public abstract class AbsSeekBar extends ProgressBar {
                }
                }
                float value = arguments.getFloat(
                float value = arguments.getFloat(
                        AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE);
                        AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE);
                return setProgress((int) value, true);
                return setProgressInternal((int) value, true, true);
            }
            }
            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
@@ -777,7 +778,7 @@ public abstract class AbsSeekBar extends ProgressBar {
                }
                }


                // Let progress bar handle clamping values.
                // Let progress bar handle clamping values.
                if (setProgress(getProgress() + increment, true)) {
                if (setProgressInternal(getProgress() + increment, true, true)) {
                    onKeyChange();
                    onKeyChange();
                    return true;
                    return true;
                }
                }
+114 −34
Original line number Original line Diff line number Diff line
@@ -16,10 +16,13 @@


package android.widget;
package android.widget;


import android.animation.ObjectAnimator;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff;


import android.util.FloatProperty;
import android.util.IntProperty;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.R;
import com.android.internal.R;


@@ -28,7 +31,6 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader;
@@ -38,7 +40,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.graphics.drawable.shapes.RoundRectShape;
import android.graphics.drawable.shapes.Shape;
import android.graphics.drawable.shapes.Shape;
@@ -57,6 +58,7 @@ import android.view.accessibility.AccessibilityManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
import android.view.animation.Transformation;
@@ -198,9 +200,17 @@ import java.util.ArrayList;
 */
 */
@RemoteView
@RemoteView
public class ProgressBar extends View {
public class ProgressBar extends View {

    private static final int MAX_LEVEL = 10000;
    private static final int MAX_LEVEL = 10000;
    private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;
    private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;


    /** Interpolator used for smooth progress animations. */
    private static final DecelerateInterpolator PROGRESS_ANIM_INTERPOLATOR =
            new DecelerateInterpolator();

    /** Duration of smooth progress animations. */
    private static final int PROGRESS_ANIM_DURATION = 80;

    int mMinWidth;
    int mMinWidth;
    int mMaxWidth;
    int mMaxWidth;
    int mMinHeight;
    int mMinHeight;
@@ -234,6 +244,9 @@ public class ProgressBar extends View {
    private boolean mAttached;
    private boolean mAttached;
    private boolean mRefreshIsPosted;
    private boolean mRefreshIsPosted;


    /** Value used to track progress animation, in the range [0...1]. */
    private float mVisualProgress;

    boolean mMirrorForRtl = false;
    boolean mMirrorForRtl = false;


    private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
    private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
@@ -814,8 +827,8 @@ public class ProgressBar extends View {
            updateDrawableBounds(getWidth(), getHeight());
            updateDrawableBounds(getWidth(), getHeight());
            updateDrawableState();
            updateDrawableState();


            doRefreshProgress(R.id.progress, mProgress, false, false);
            doRefreshProgress(R.id.progress, mProgress, false, false, false);
            doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false);
            doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false, false);
        }
        }
    }
    }


@@ -1246,7 +1259,7 @@ public class ProgressBar extends View {
                final int count = mRefreshData.size();
                final int count = mRefreshData.size();
                for (int i = 0; i < count; i++) {
                for (int i = 0; i < count; i++) {
                    final RefreshData rd = mRefreshData.get(i);
                    final RefreshData rd = mRefreshData.get(i);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true, rd.animate);
                    rd.recycle();
                    rd.recycle();
                }
                }
                mRefreshData.clear();
                mRefreshData.clear();
@@ -1263,8 +1276,9 @@ public class ProgressBar extends View {
        public int id;
        public int id;
        public int progress;
        public int progress;
        public boolean fromUser;
        public boolean fromUser;
        public boolean animate;


        public static RefreshData obtain(int id, int progress, boolean fromUser) {
        public static RefreshData obtain(int id, int progress, boolean fromUser, boolean animate) {
            RefreshData rd = sPool.acquire();
            RefreshData rd = sPool.acquire();
            if (rd == null) {
            if (rd == null) {
                rd = new RefreshData();
                rd = new RefreshData();
@@ -1272,6 +1286,7 @@ public class ProgressBar extends View {
            rd.id = id;
            rd.id = id;
            rd.progress = progress;
            rd.progress = progress;
            rd.fromUser = fromUser;
            rd.fromUser = fromUser;
            rd.animate = animate;
            return rd;
            return rd;
        }
        }


@@ -1281,26 +1296,21 @@ public class ProgressBar extends View {
    }
    }


    private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
    private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
            boolean callBackToApp) {
            boolean callBackToApp, boolean animate) {
        float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
        final float scale = mMax > 0 ? progress / (float) mMax : 0;
        final Drawable d = mCurrentDrawable;
        final boolean isPrimary = id == R.id.progress;
        if (d != null) {

            Drawable progressDrawable = null;
        if (isPrimary && animate) {

            final ObjectAnimator animator = ObjectAnimator.ofFloat(this, VISUAL_PROGRESS, scale);
            if (d instanceof LayerDrawable) {
            animator.setAutoCancel(true);
                progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id);
            animator.setDuration(PROGRESS_ANIM_DURATION);
                if (progressDrawable != null && canResolveLayoutDirection()) {
            animator.setInterpolator(PROGRESS_ANIM_INTERPOLATOR);
                    progressDrawable.setLayoutDirection(getLayoutDirection());
            animator.start();
                }
            }

            final int level = (int) (scale * MAX_LEVEL);
            (progressDrawable != null ? progressDrawable : d).setLevel(level);
        } else {
        } else {
            invalidate();
            setVisualProgress(id, scale);
        }
        }


        if (callBackToApp && id == R.id.progress) {
        if (isPrimary && callBackToApp) {
            onProgressRefresh(scale, fromUser, progress);
            onProgressRefresh(scale, fromUser, progress);
        }
        }
    }
    }
@@ -1311,15 +1321,51 @@ public class ProgressBar extends View {
        }
        }
    }
    }


    private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
    /**
     * Sets the visual state of a progress indicator.
     *
     * @param id the identifier of the progress indicator
     * @param progress the visual progress in the range [0...1]
     */
    private void setVisualProgress(int id, float progress) {
        mVisualProgress = progress;

        Drawable d = mCurrentDrawable;

        if (d instanceof LayerDrawable) {
            d = ((LayerDrawable) d).findDrawableByLayerId(id);
        }

        if (d != null) {
            final int level = (int) (progress * MAX_LEVEL);
            d.setLevel(level);
        } else {
            invalidate();
        }

        onVisualProgressChanged(id, progress);
    }

    /**
     * Called when the visual state of a progress indicator changes.
     *
     * @param id the identifier of the progress indicator
     * @param progress the visual progress in the range [0...1]
     */
    void onVisualProgressChanged(int id, float progress) {
        // Stub method.
    }

    private synchronized void refreshProgress(int id, int progress, boolean fromUser,
            boolean animate) {
        if (mUiThreadId == Thread.currentThread().getId()) {
        if (mUiThreadId == Thread.currentThread().getId()) {
            doRefreshProgress(id, progress, fromUser, true);
            doRefreshProgress(id, progress, fromUser, true, animate);
        } else {
        } else {
            if (mRefreshProgressRunnable == null) {
            if (mRefreshProgressRunnable == null) {
                mRefreshProgressRunnable = new RefreshProgressRunnable();
                mRefreshProgressRunnable = new RefreshProgressRunnable();
            }
            }


            final RefreshData rd = RefreshData.obtain(id, progress, fromUser);
            final RefreshData rd = RefreshData.obtain(id, progress, fromUser, animate);
            mRefreshData.add(rd);
            mRefreshData.add(rd);
            if (mAttached && !mRefreshIsPosted) {
            if (mAttached && !mRefreshIsPosted) {
                post(mRefreshProgressRunnable);
                post(mRefreshProgressRunnable);
@@ -1329,8 +1375,8 @@ public class ProgressBar extends View {
    }
    }


    /**
    /**
     * <p>Set the current progress to the specified value. Does not do anything
     * Sets the current progress to the specified value. Does not do anything
     * if the progress bar is in indeterminate mode.</p>
     * if the progress bar is in indeterminate mode.
     *
     *
     * @param progress the new progress, between 0 and {@link #getMax()}
     * @param progress the new progress, between 0 and {@link #getMax()}
     *
     *
@@ -1341,11 +1387,26 @@ public class ProgressBar extends View {
     */
     */
    @android.view.RemotableViewMethod
    @android.view.RemotableViewMethod
    public synchronized void setProgress(int progress) {
    public synchronized void setProgress(int progress) {
        setProgress(progress, false);
        setProgressInternal(progress, false, false);
    }

    /**
     * Sets the current progress to the specified value, optionally animating
     * between the current and target values.
     * <p>
     * Animation does not affect the result of {@link #getProgress()}, which
     * will return the target value immediately after this method is called.
     *
     * @param progress the new progress value, between 0 and {@link #getMax()}
     * @param animate {@code true} to animate between the current and target
     *                values or {@code false} to not animate
     */
    public void setProgress(int progress, boolean animate) {
        setProgressInternal(progress, false, animate);
    }
    }


    @android.view.RemotableViewMethod
    @android.view.RemotableViewMethod
    synchronized boolean setProgress(int progress, boolean fromUser) {
    synchronized boolean setProgressInternal(int progress, boolean fromUser, boolean animate) {
        if (mIndeterminate) {
        if (mIndeterminate) {
            // Not applicable.
            // Not applicable.
            return false;
            return false;
@@ -1359,7 +1420,7 @@ public class ProgressBar extends View {
        }
        }


        mProgress = progress;
        mProgress = progress;
        refreshProgress(R.id.progress, mProgress, fromUser);
        refreshProgress(R.id.progress, mProgress, fromUser, animate);
        return true;
        return true;
    }
    }


@@ -1391,7 +1452,7 @@ public class ProgressBar extends View {


        if (secondaryProgress != mSecondaryProgress) {
        if (secondaryProgress != mSecondaryProgress) {
            mSecondaryProgress = secondaryProgress;
            mSecondaryProgress = secondaryProgress;
            refreshProgress(R.id.secondaryProgress, mSecondaryProgress, false);
            refreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false);
        }
        }
    }
    }


@@ -1464,7 +1525,7 @@ public class ProgressBar extends View {
            if (mProgress > max) {
            if (mProgress > max) {
                mProgress = max;
                mProgress = max;
            }
            }
            refreshProgress(R.id.progress, mProgress, false);
            refreshProgress(R.id.progress, mProgress, false, false);
        }
        }
    }
    }


@@ -1847,7 +1908,7 @@ public class ProgressBar extends View {
                final int count = mRefreshData.size();
                final int count = mRefreshData.size();
                for (int i = 0; i < count; i++) {
                for (int i = 0; i < count; i++) {
                    final RefreshData rd = mRefreshData.get(i);
                    final RefreshData rd = mRefreshData.get(i);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true, rd.animate);
                    rd.recycle();
                    rd.recycle();
                }
                }
                mRefreshData.clear();
                mRefreshData.clear();
@@ -1956,4 +2017,23 @@ public class ProgressBar extends View {
        boolean mHasSecondaryProgressTint;
        boolean mHasSecondaryProgressTint;
        boolean mHasSecondaryProgressTintMode;
        boolean mHasSecondaryProgressTintMode;
    }
    }

    /**
     * Property wrapper around the visual state of the {@code progress} functionality
     * handled by the {@link ProgressBar#setProgress(int, boolean)} method. This does
     * not correspond directly to the actual progress -- only the visual state.
     */
    private final FloatProperty<ProgressBar> VISUAL_PROGRESS =
            new FloatProperty<ProgressBar>("visual_progress") {
                @Override
                public void setValue(ProgressBar object, float value) {
                    object.setVisualProgress(R.id.progress, value);
                    object.mVisualProgress = value;
                }

                @Override
                public Float get(ProgressBar object) {
                    return object.mVisualProgress;
                }
            };
}
}
+10 −49
Original line number Original line Diff line number Diff line
@@ -89,7 +89,6 @@ public class VolumeDialog {


    private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
    private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
    private static final int WAIT_FOR_RIPPLE = 200;
    private static final int WAIT_FOR_RIPPLE = 200;
    private static final int UPDATE_ANIMATION_DURATION = 80;


    private final Context mContext;
    private final Context mContext;
    private final H mHandler = new H();
    private final H mHandler = new H();
@@ -353,14 +352,6 @@ public class VolumeDialog {
        writer.println(mAccessibility.mFeedbackEnabled);
        writer.println(mAccessibility.mFeedbackEnabled);
    }
    }


    private static int getImpliedLevel(SeekBar seekBar, int progress) {
        final int m = seekBar.getMax();
        final int n = m / 100 - 1;
        final int level = progress == 0 ? 0
                : progress == m ? (m / 100) : (1 + (int)((progress / (float) m) * n));
        return level;
    }

    @SuppressLint("InflateParams")
    @SuppressLint("InflateParams")
    private VolumeRow initRow(final int stream, int iconRes, int iconMuteRes, boolean important) {
    private VolumeRow initRow(final int stream, int iconRes, int iconMuteRes, boolean important) {
        final VolumeRow row = new VolumeRow();
        final VolumeRow row = new VolumeRow();
@@ -690,7 +681,7 @@ public class VolumeDialog {
                : false;
                : false;


        // update slider max
        // update slider max
        final int max = ss.levelMax * 100;
        final int max = ss.levelMax;
        if (max != row.slider.getMax()) {
        if (max != row.slider.getMax()) {
            row.slider.setMax(max);
            row.slider.setMax(max);
        }
        }
@@ -777,8 +768,7 @@ public class VolumeDialog {
        if (row.tracking) {
        if (row.tracking) {
            return;  // don't update if user is sliding
            return;  // don't update if user is sliding
        }
        }
        final int progress = row.slider.getProgress();
        final int level = row.slider.getProgress();
        final int level = getImpliedLevel(row.slider, progress);
        final boolean rowVisible = row.view.getVisibility() == View.VISIBLE;
        final boolean rowVisible = row.view.getVisibility() == View.VISIBLE;
        final boolean inGracePeriod = (SystemClock.uptimeMillis() - row.userAttempt)
        final boolean inGracePeriod = (SystemClock.uptimeMillis() - row.userAttempt)
                < USER_ATTEMPT_GRACE_PERIOD;
                < USER_ATTEMPT_GRACE_PERIOD;
@@ -794,33 +784,7 @@ public class VolumeDialog {
                return;  // don't clamp if visible
                return;  // don't clamp if visible
            }
            }
        }
        }
        final int newProgress = vlevel * 100;
        row.slider.setProgress(vlevel, true);
        if (progress != newProgress) {
            if (mShowing && rowVisible) {
                // animate!
                if (row.anim != null && row.anim.isRunning()
                        && row.animTargetProgress == newProgress) {
                    return;  // already animating to the target progress
                }
                // start/update animation
                if (row.anim == null) {
                    row.anim = ObjectAnimator.ofInt(row.slider, "progress", progress, newProgress);
                    row.anim.setInterpolator(new DecelerateInterpolator());
                } else {
                    row.anim.cancel();
                    row.anim.setIntValues(progress, newProgress);
                }
                row.animTargetProgress = newProgress;
                row.anim.setDuration(UPDATE_ANIMATION_DURATION);
                row.anim.start();
            } else {
                // update slider directly to clamped value
                if (row.anim != null) {
                    row.anim.cancel();
                }
                row.slider.setProgress(newProgress);
            }
        }
    }
    }


    private void recheckH(VolumeRow row) {
    private void recheckH(VolumeRow row) {
@@ -1025,20 +989,19 @@ public class VolumeDialog {
                    + " onProgressChanged " + progress + " fromUser=" + fromUser);
                    + " onProgressChanged " + progress + " fromUser=" + fromUser);
            if (!fromUser) return;
            if (!fromUser) return;
            if (mRow.ss.levelMin > 0) {
            if (mRow.ss.levelMin > 0) {
                final int minProgress = mRow.ss.levelMin * 100;
                final int minProgress = mRow.ss.levelMin;
                if (progress < minProgress) {
                if (progress < minProgress) {
                    seekBar.setProgress(minProgress);
                    seekBar.setProgress(minProgress);
                    progress = minProgress;
                    progress = minProgress;
                }
                }
            }
            }
            final int userLevel = getImpliedLevel(seekBar, progress);
            if (mRow.ss.level != progress || mRow.ss.muted && progress > 0) {
            if (mRow.ss.level != userLevel || mRow.ss.muted && userLevel > 0) {
                mRow.userAttempt = SystemClock.uptimeMillis();
                mRow.userAttempt = SystemClock.uptimeMillis();
                if (mRow.requestedLevel != userLevel) {
                if (mRow.requestedLevel != progress) {
                    mController.setStreamVolume(mRow.stream, userLevel);
                    mController.setStreamVolume(mRow.stream, progress);
                    mRow.requestedLevel = userLevel;
                    mRow.requestedLevel = progress;
                    Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream,
                    Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream,
                            userLevel);
                            progress);
                }
                }
            }
            }
        }
        }
@@ -1055,7 +1018,7 @@ public class VolumeDialog {
            if (D.BUG) Log.d(TAG, "onStopTrackingTouch"+ " " + mRow.stream);
            if (D.BUG) Log.d(TAG, "onStopTrackingTouch"+ " " + mRow.stream);
            mRow.tracking = false;
            mRow.tracking = false;
            mRow.userAttempt = SystemClock.uptimeMillis();
            mRow.userAttempt = SystemClock.uptimeMillis();
            int userLevel = getImpliedLevel(seekBar, seekBar.getProgress());
            final int userLevel = seekBar.getProgress();
            Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_DONE, mRow.stream, userLevel);
            Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_DONE, mRow.stream, userLevel);
            if (mRow.ss.level != userLevel) {
            if (mRow.ss.level != userLevel) {
                mHandler.sendMessageDelayed(mHandler.obtainMessage(H.RECHECK, mRow),
                mHandler.sendMessageDelayed(mHandler.obtainMessage(H.RECHECK, mRow),
@@ -1137,8 +1100,6 @@ public class VolumeDialog {
        private int iconState;  // from Events
        private int iconState;  // from Events
        private boolean cachedShowHeaders = VolumePrefs.DEFAULT_SHOW_HEADERS;
        private boolean cachedShowHeaders = VolumePrefs.DEFAULT_SHOW_HEADERS;
        private int cachedExpandButtonRes;
        private int cachedExpandButtonRes;
        private ObjectAnimator anim;  // slider progress animation for non-touch-related updates
        private int animTargetProgress;
        private int lastAudibleLevel = 1;
        private int lastAudibleLevel = 1;
    }
    }