| Index: content/public/android/java/src/org/chromium/content/browser/SmoothScroller.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/SmoothScroller.java b/content/public/android/java/src/org/chromium/content/browser/SmoothScroller.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d2999f4161467efffa47cc1ce78997ba0743c402
|
| --- /dev/null
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/SmoothScroller.java
|
| @@ -0,0 +1,120 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.content.browser;
|
| +
|
| +import android.animation.TimeAnimator;
|
| +import android.animation.TimeAnimator.TimeListener;
|
| +import android.os.Build;
|
| +import android.os.Handler;
|
| +import android.os.Looper;
|
| +import android.os.SystemClock;
|
| +import android.util.Log;
|
| +import android.view.MotionEvent;
|
| +
|
| +import org.chromium.base.CalledByNative;
|
| +import org.chromium.base.JNINamespace;
|
| +
|
| +/**
|
| + * Provides a Java-side implementation for chrome.gpuBenchmarking.smoothScrollBy.
|
| + */
|
| +@JNINamespace("content")
|
| +public class SmoothScroller {
|
| + final ContentViewCore mContentViewCore;
|
| + final boolean mScrollDown;
|
| + final float mMouseEventX;
|
| + final float mMouseEventY;
|
| +
|
| + final Handler mHandler = new Handler(Looper.getMainLooper());
|
| +
|
| + TimeAnimator mTimeAnimator;
|
| +
|
| + int mNativePtr;
|
| + long mDownTime;
|
| + float mCurrentY;
|
| +
|
| + boolean mHasSentUp = false;
|
| +
|
| + SmoothScroller(ContentViewCore contentViewCore, boolean scrollDown,
|
| + int mouseEventX, int mouseEventY) {
|
| + mContentViewCore = contentViewCore;
|
| + mScrollDown = scrollDown;
|
| + float scale = mContentViewCore.getScale();
|
| + mMouseEventX = mouseEventX * scale;
|
| + mMouseEventY = mouseEventY * scale;
|
| + mCurrentY = mMouseEventY;
|
| + }
|
| +
|
| + @CalledByNative
|
| + void start(int nativePtr) {
|
| + assert mNativePtr == 0;
|
| + mNativePtr = nativePtr;
|
| +
|
| + mDownTime = SystemClock.uptimeMillis();
|
| + MotionEvent event = MotionEvent.obtain(mDownTime, mDownTime,
|
| + MotionEvent.ACTION_DOWN, mMouseEventX, mCurrentY, 0);
|
| + mContentViewCore.onTouchEvent(event);
|
| + event.recycle();
|
| +
|
| + Runnable runnable = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ?
|
| + createJBRunnable() : createPreJBRunnable();
|
| + mHandler.post(runnable);
|
| + }
|
| +
|
| + boolean sendEvent(long time) {
|
| + float delta = nativeTick(mNativePtr) * mContentViewCore.getScale();
|
| + if (delta != 0) {
|
| + mCurrentY += mScrollDown ? -delta : delta;
|
| +
|
| + MotionEvent event = MotionEvent.obtain(mDownTime, time,
|
| + MotionEvent.ACTION_MOVE, mMouseEventX, mCurrentY, 0);
|
| + mContentViewCore.onTouchEvent(event);
|
| + event.recycle();
|
| + }
|
| + boolean hasFinished = nativeHasFinished(mNativePtr);
|
| + if (hasFinished && !mHasSentUp) {
|
| + mHasSentUp = true;
|
| + MotionEvent event = MotionEvent.obtain(mDownTime, time,
|
| + MotionEvent.ACTION_UP, mMouseEventX, mCurrentY, 0);
|
| + mContentViewCore.onTouchEvent(event);
|
| + event.recycle();
|
| + }
|
| + return !hasFinished;
|
| + }
|
| +
|
| + private Runnable createJBRunnable() {
|
| + // On JB, we rely on TimeAnimator to send events tied with vsync.
|
| + return new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + mTimeAnimator = new TimeAnimator();
|
| + mTimeAnimator.setTimeListener(new TimeListener() {
|
| + @Override
|
| + public void onTimeUpdate(TimeAnimator animation, long totalTime,
|
| + long deltaTime) {
|
| + if (!sendEvent(mDownTime + totalTime)) {
|
| + mTimeAnimator.end();
|
| + }
|
| + }
|
| + });
|
| + mTimeAnimator.start();
|
| + }
|
| + };
|
| + }
|
| +
|
| + private Runnable createPreJBRunnable() {
|
| + // Pre-JB there's no TimeAnimator, so we keep posting messages.
|
| + return new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + if (!sendEvent(SystemClock.uptimeMillis())) {
|
| + mHandler.post(this);
|
| + }
|
| + }
|
| + };
|
| + }
|
| +
|
| + private native int nativeTick(int nativeSmoothScrollGestureAndroid);
|
| + private native boolean nativeHasFinished(int nativeSmoothScrollGestureAndroid);
|
| +}
|
|
|