| Index: content/public/android/java/src/org/chromium/content/browser/input/JoystickScrollProvider.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/input/JoystickScrollProvider.java b/content/public/android/java/src/org/chromium/content/browser/input/JoystickScrollProvider.java
|
| index 1336b78b3982b6630d0ad30e90bbc4cf88c6ee73..8c57b5f8f8531fb34f99ba8a4890ca492b78903d 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/input/JoystickScrollProvider.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/input/JoystickScrollProvider.java
|
| @@ -4,17 +4,25 @@
|
|
|
| package org.chromium.content.browser.input;
|
|
|
| +import android.content.Context;
|
| import android.util.TypedValue;
|
| import android.view.InputDevice;
|
| import android.view.MotionEvent;
|
| +import android.view.View;
|
| import android.view.animation.AnimationUtils;
|
|
|
| import org.chromium.base.Log;
|
| -import org.chromium.content.browser.ContentViewCore;
|
| +import org.chromium.base.annotations.CalledByNative;
|
| +import org.chromium.base.annotations.JNINamespace;
|
| +import org.chromium.content_public.browser.WebContents;
|
| +import org.chromium.ui.base.WindowAndroid;
|
| +import org.chromium.ui.display.DisplayAndroid;
|
| +import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver;
|
|
|
| /**
|
| * This class implements auto scrolling and panning for gamepad left joystick motion event.
|
| */
|
| +@JNINamespace("content")
|
| public class JoystickScrollProvider {
|
| private static final String TAG = "JoystickScroll";
|
|
|
| @@ -24,11 +32,26 @@ public class JoystickScrollProvider {
|
| private static final float JOYSTICK_SCROLL_DEADZONE = 0.2f;
|
| private static final float SCROLL_FACTOR_FALLBACK = 128f;
|
|
|
| - private final ContentViewCore mView;
|
| + private class JoystickScrollDisplayObserver implements DisplayAndroidObserver {
|
| + @Override
|
| + public void onRotationChanged(int rotation) {}
|
| +
|
| + @Override
|
| + public void onDIPScaleChanged(float dipScale) {
|
| + mDipScale = dipScale;
|
| + updateScrollFactor();
|
| + }
|
| + }
|
| +
|
| + private WindowAndroid mWindowAndroid;
|
| + private View mContainerView;
|
| + private long mNativeJoystickScrollProvider;
|
| + private JoystickScrollDisplayObserver mDisplayObserver;
|
|
|
| private float mScrollVelocityX;
|
| private float mScrollVelocityY;
|
| private float mScrollFactor;
|
| + private float mDipScale = 1.0f;
|
|
|
| private long mLastAnimateTimeMillis;
|
|
|
| @@ -38,12 +61,20 @@ public class JoystickScrollProvider {
|
|
|
| /**
|
| * Constructs a new JoystickScrollProvider.
|
| - *
|
| - * @param contentview The ContentViewCore used to create this.
|
| */
|
| - public JoystickScrollProvider(ContentViewCore contentView) {
|
| - mView = contentView;
|
| + public JoystickScrollProvider(
|
| + WebContents webContents, View containerView, WindowAndroid windowAndroid) {
|
| + mNativeJoystickScrollProvider = nativeInit(webContents);
|
| + mContainerView = containerView;
|
| + mWindowAndroid = windowAndroid;
|
| mEnabled = true;
|
| + mDisplayObserver = new JoystickScrollDisplayObserver();
|
| + }
|
| +
|
| + @CalledByNative
|
| + private void onNativeObjectDestroyed(long nativePointer) {
|
| + assert nativePointer == mNativeJoystickScrollProvider;
|
| + mNativeJoystickScrollProvider = 0;
|
| }
|
|
|
| /**
|
| @@ -56,6 +87,49 @@ public class JoystickScrollProvider {
|
| if (!enabled) stop();
|
| }
|
|
|
| + public void onViewAttachedToWindow() {
|
| + addDisplayAndroidObserver();
|
| + }
|
| +
|
| + public void onViewDetachedFromWindow() {
|
| + removeDisplayAndroidObserver();
|
| + }
|
| +
|
| + public void updateWindowAndroid(WindowAndroid windowAndroid) {
|
| + removeDisplayAndroidObserver();
|
| + mWindowAndroid = windowAndroid;
|
| + addDisplayAndroidObserver();
|
| + }
|
| +
|
| + private void addDisplayAndroidObserver() {
|
| + if (mWindowAndroid == null) return;
|
| +
|
| + DisplayAndroid display = mWindowAndroid.getDisplay();
|
| + display.addObserver(mDisplayObserver);
|
| + mDisplayObserver.onDIPScaleChanged(display.getDipScale());
|
| + }
|
| +
|
| + private void removeDisplayAndroidObserver() {
|
| + if (mWindowAndroid == null) return;
|
| + mWindowAndroid.getDisplay().removeObserver(mDisplayObserver);
|
| + }
|
| +
|
| + private void updateScrollFactor() {
|
| + Context context = mWindowAndroid == null ? null : mWindowAndroid.getContext().get();
|
| + TypedValue outValue = new TypedValue();
|
| +
|
| + if (context != null && context.getTheme().resolveAttribute(
|
| + android.R.attr.listPreferredItemHeight, outValue, true)) {
|
| + mScrollFactor = outValue.getDimension(context.getResources().getDisplayMetrics());
|
| + } else {
|
| + if (context != null) {
|
| + Log.d(TAG, "Theme attribute listPreferredItemHeight not defined"
|
| + + " switching to fallback scroll factor");
|
| + }
|
| + mScrollFactor = SCROLL_FACTOR_FALLBACK * mDipScale;
|
| + }
|
| + }
|
| +
|
| /**
|
| * This function processes motion event and computes new
|
| * scroll offest in pixels which is propertional to left joystick
|
| @@ -72,7 +146,13 @@ public class JoystickScrollProvider {
|
| Log.d(TAG, "Joystick left stick axis: " + event.getAxisValue(MotionEvent.AXIS_X) + ","
|
| + event.getAxisValue(MotionEvent.AXIS_Y));
|
|
|
| - computeNewScrollVelocity(event);
|
| + assert mScrollFactor != 0;
|
| +
|
| + mScrollVelocityX = getFilteredAxisValue(event, MotionEvent.AXIS_X) * mScrollFactor
|
| + * JOYSTICK_SCROLL_FACTOR_MULTIPLIER;
|
| + mScrollVelocityY = getFilteredAxisValue(event, MotionEvent.AXIS_Y) * mScrollFactor
|
| + * JOYSTICK_SCROLL_FACTOR_MULTIPLIER;
|
| +
|
| if (mScrollVelocityX == 0 && mScrollVelocityY == 0) {
|
| stop();
|
| return false;
|
| @@ -86,7 +166,7 @@ public class JoystickScrollProvider {
|
| };
|
| }
|
| if (mLastAnimateTimeMillis == 0) {
|
| - mView.getContainerView().postOnAnimation(mScrollRunnable);
|
| + mContainerView.postOnAnimation(mScrollRunnable);
|
| mLastAnimateTimeMillis = AnimationUtils.currentAnimationTimeMillis();
|
| }
|
| return true;
|
| @@ -100,9 +180,14 @@ public class JoystickScrollProvider {
|
| final long dt = timeMillis - mLastAnimateTimeMillis;
|
| final float dx = (mScrollVelocityX * dt / 1000.f);
|
| final float dy = (mScrollVelocityY * dt / 1000.f);
|
| - mView.scrollBy(dx, dy, true);
|
| +
|
| + if (mNativeJoystickScrollProvider != 0) {
|
| + nativeScrollBy(
|
| + mNativeJoystickScrollProvider, timeMillis, dx / mDipScale, dy / mDipScale);
|
| + }
|
| +
|
| mLastAnimateTimeMillis = timeMillis;
|
| - mView.getContainerView().postOnAnimation(mScrollRunnable);
|
| + mContainerView.postOnAnimation(mScrollRunnable);
|
| }
|
|
|
| private void stop() {
|
| @@ -110,29 +195,6 @@ public class JoystickScrollProvider {
|
| }
|
|
|
| /**
|
| - * Translates joystick axes movement to a scroll velocity.
|
| - */
|
| - private void computeNewScrollVelocity(MotionEvent event) {
|
| - if (mScrollFactor == 0) {
|
| - TypedValue outValue = new TypedValue();
|
| - if (!mView.getContext().getTheme().resolveAttribute(
|
| - android.R.attr.listPreferredItemHeight, outValue, true)) {
|
| - mScrollFactor = outValue.getDimension(
|
| - mView.getContext().getResources().getDisplayMetrics());
|
| - } else {
|
| - Log.d(TAG, "Theme attribute listPreferredItemHeight not defined"
|
| - + "switching to fallback scroll factor ");
|
| - mScrollFactor = SCROLL_FACTOR_FALLBACK
|
| - * mView.getRenderCoordinates().getDeviceScaleFactor();
|
| - }
|
| - }
|
| - mScrollVelocityX = getFilteredAxisValue(event, MotionEvent.AXIS_X) * mScrollFactor
|
| - * JOYSTICK_SCROLL_FACTOR_MULTIPLIER;
|
| - mScrollVelocityY = getFilteredAxisValue(event, MotionEvent.AXIS_Y) * mScrollFactor
|
| - * JOYSTICK_SCROLL_FACTOR_MULTIPLIER;
|
| - }
|
| -
|
| - /**
|
| * Removes noise from joystick motion events.
|
| */
|
| private float getFilteredAxisValue(MotionEvent event, int axis) {
|
| @@ -143,4 +205,8 @@ public class JoystickScrollProvider {
|
| }
|
| return 0f;
|
| }
|
| +
|
| + private native long nativeInit(WebContents webContents);
|
| + private native void nativeScrollBy(
|
| + long nativeJoystickScrollProvider, long timeMs, float dxDip, float dyDip);
|
| }
|
|
|