Commit 78627331 authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Commit Bot

Scroll events through EventForwarder

This CL is moving the 2 other gesture events (scroll/doubletap)
flow to EventForwarder, and removes the related logic from
ContentViewCore.

Bug: 598880
Change-Id: Ie52de9f5074e7921184d394154c82e20284e057d
Reviewed-on: https://chromium-review.googlesource.com/935601Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540981}
parent 8339c1bf
......@@ -700,7 +700,7 @@ public class AwContents implements SmartClipProvider {
@Override
public void cancelFling() {
mWebContents.getEventForwarder().onCancelFling(SystemClock.uptimeMillis());
mWebContents.getEventForwarder().cancelFling(SystemClock.uptimeMillis());
}
}
......@@ -2273,7 +2273,7 @@ public class AwContents implements SmartClipProvider {
public void flingScroll(int velocityX, int velocityY) {
if (TRACE) Log.i(TAG, "%s flingScroll", this);
if (isDestroyedOrNoOperation(WARN)) return;
mWebContents.getEventForwarder().onStartFling(
mWebContents.getEventForwarder().startFling(
SystemClock.uptimeMillis(), -velocityX, -velocityY, false);
}
......
......@@ -3322,7 +3322,8 @@ public class AwSettingsTest {
final int y = (webView.getBottom() - webView.getTop()) / 2;
final AwContents awContents = webView.getAwContents();
InstrumentationRegistry.getInstrumentation().runOnMainSync(
() -> awContents.getContentViewCore().sendDoubleTapForTest(
SystemClock.uptimeMillis(), x, y));
()
-> awContents.getWebContents().getEventForwarder().doubleTapForTest(
SystemClock.uptimeMillis(), x, y));
}
}
......@@ -1384,8 +1384,7 @@ public class TabsTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
WebContents webContents =
mActivityTestRule.getActivity().getActivityTab().getWebContents();
webContents.getEventForwarder().onStartFling(
SystemClock.uptimeMillis(), 0, -2000, false);
webContents.getEventForwarder().startFling(SystemClock.uptimeMillis(), 0, -2000, false);
});
ChromeTabUtils.closeCurrentTab(
InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
......
......@@ -25,7 +25,6 @@
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/input/web_input_event_builders_android.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
......@@ -414,78 +413,6 @@ void ContentViewCore::SendOrientationChangeEvent(
}
}
WebGestureEvent ContentViewCore::MakeGestureEvent(WebInputEvent::Type type,
int64_t time_ms,
float x,
float y) const {
return WebGestureEventBuilder::Build(type, time_ms / 1000.0, x / dpi_scale(),
y / dpi_scale());
}
void ContentViewCore::SendGestureEvent(const blink::WebGestureEvent& event) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->SendGestureEvent(event);
}
void ContentViewCore::ScrollBegin(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
jfloat hintx,
jfloat hinty,
jboolean target_viewport,
jboolean from_gamepad) {
WebGestureEvent event =
MakeGestureEvent(WebInputEvent::kGestureScrollBegin, time_ms, x, y);
event.data.scroll_begin.delta_x_hint = hintx / dpi_scale();
event.data.scroll_begin.delta_y_hint = hinty / dpi_scale();
event.data.scroll_begin.target_viewport = target_viewport;
if (from_gamepad)
event.source_device = blink::kWebGestureDeviceSyntheticAutoscroll;
SendGestureEvent(event);
}
void ContentViewCore::ScrollEnd(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong time_ms) {
WebGestureEvent event =
MakeGestureEvent(WebInputEvent::kGestureScrollEnd, time_ms, 0, 0);
SendGestureEvent(event);
}
void ContentViewCore::ScrollBy(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
jfloat dx,
jfloat dy) {
WebGestureEvent event =
MakeGestureEvent(WebInputEvent::kGestureScrollUpdate, time_ms, x, y);
event.data.scroll_update.delta_x = -dx / dpi_scale();
event.data.scroll_update.delta_y = -dy / dpi_scale();
SendGestureEvent(event);
}
void ContentViewCore::DoubleTap(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y) {
WebGestureEvent event =
MakeGestureEvent(WebInputEvent::kGestureDoubleTap, time_ms, x, y);
// Set the tap count to 1 even for DoubleTap, in order to be consistent with
// double tap behavior on a mobile viewport. See crbug.com/234986 for context.
event.data.tap.tap_count = 1;
SendGestureEvent(event);
}
void ContentViewCore::SetTextHandlesTemporarilyHidden(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
......
......@@ -84,30 +84,6 @@ class ContentViewCore : public WebContentsObserver {
jfloat ticks_x,
jfloat ticks_y,
jfloat pixels_per_tick);
void ScrollBegin(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
jfloat hintx,
jfloat hinty,
jboolean target_viewport,
jboolean from_gamepad);
void ScrollEnd(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jlong time_ms);
void ScrollBy(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
jfloat dx,
jfloat dy);
void DoubleTap(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y);
void SetTextHandlesTemporarilyHidden(
JNIEnv* env,
......@@ -211,15 +187,8 @@ class ContentViewCore : public WebContentsObserver {
RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid() const;
blink::WebGestureEvent MakeGestureEvent(blink::WebInputEvent::Type type,
int64_t time_ms,
float x,
float y) const;
gfx::Size GetViewportSizePix() const;
void SendGestureEvent(const blink::WebGestureEvent& event);
// Update focus state of the RenderWidgetHostView.
void SetFocusInternal(bool focused);
......
......@@ -469,13 +469,6 @@ public class ContentViewCoreImpl implements ContentViewCore, DisplayAndroidObser
getSelectionPopupController().setScrollInProgress(touchScrollInProgress, scrollInProgress);
}
@VisibleForTesting
@Override
public void sendDoubleTapForTest(long timeMs, int x, int y) {
if (mNativeContentViewCore == 0) return;
nativeDoubleTap(mNativeContentViewCore, timeMs, x, y);
}
@Override
public void onShow() {
assert mWebContents != null;
......@@ -717,24 +710,19 @@ public class ContentViewCoreImpl implements ContentViewCore, DisplayAndroidObser
@Override
public void scrollBy(float dxPix, float dyPix) {
if (mNativeContentViewCore == 0) return;
if (dxPix == 0 && dyPix == 0) return;
long time = SystemClock.uptimeMillis();
// It's a very real (and valid) possibility that a fling may still
// be active when programatically scrolling. Cancelling the fling in
// such cases ensures a consistent gesture event stream.
if (getGestureListenerManager().hasPotentiallyActiveFling()) {
getEventForwarder().onCancelFling(time);
getEventForwarder().cancelFling(time);
}
// x/y represents starting location of scroll.
nativeScrollBegin(mNativeContentViewCore, time, 0f, 0f, -dxPix, -dyPix, true, false);
nativeScrollBy(mNativeContentViewCore, time, 0f, 0f, dxPix, dyPix);
nativeScrollEnd(mNativeContentViewCore, time);
getEventForwarder().scroll(time, dxPix, dyPix);
}
@Override
public void scrollTo(float xPix, float yPix) {
if (mNativeContentViewCore == 0) return;
final float xCurrentPix = mRenderCoordinates.getScrollXPix();
final float yCurrentPix = mRenderCoordinates.getScrollYPix();
final float dxPix = xPix - xCurrentPix;
......@@ -983,12 +971,6 @@ public class ContentViewCoreImpl implements ContentViewCore, DisplayAndroidObser
long nativeContentViewCore);
private native void nativeSendOrientationChangeEvent(
long nativeContentViewCore, int orientation);
private native void nativeScrollBegin(long nativeContentViewCore, long timeMs, float x, float y,
float hintX, float hintY, boolean targetViewport, boolean fromGamepad);
private native void nativeScrollEnd(long nativeContentViewCore, long timeMs);
private native void nativeScrollBy(
long nativeContentViewCore, long timeMs, float x, float y, float deltaX, float deltaY);
private native void nativeDoubleTap(long nativeContentViewCore, long timeMs, float x, float y);
private native void nativeSetTextHandlesTemporarilyHidden(
long nativeContentViewCore, boolean hidden);
private native void nativeResetGestureDetection(long nativeContentViewCore);
......
......@@ -58,7 +58,7 @@ class JoystickHandler implements ImeEventObserver {
float velocityX = getVelocityFromJoystickAxis(event, MotionEvent.AXIS_X);
float velocityY = getVelocityFromJoystickAxis(event, MotionEvent.AXIS_Y);
if (velocityX == 0.f && velocityY == 0.f) return false;
mEventForwarder.onStartFling(event.getEventTime(), velocityX, velocityY, true);
mEventForwarder.startFling(event.getEventTime(), velocityX, velocityY, true);
return true;
}
......
......@@ -328,9 +328,6 @@ public interface ContentViewCore {
@VisibleForTesting
int getTopControlsShrinkBlinkHeightForTesting();
@VisibleForTesting
void sendDoubleTapForTest(long timeMs, int x, int y);
/**
* @return {@code true} if select popup is being shown.
*/
......
......@@ -125,7 +125,7 @@ public class ContentViewScrollingTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
mActivityTestRule.getWebContents().getEventForwarder().onStartFling(
mActivityTestRule.getWebContents().getEventForwarder().startFling(
SystemClock.uptimeMillis(), vx, vy, false);
}
});
......
......@@ -80,9 +80,6 @@ public class TestContentViewCore implements ContentViewCore {
return false;
}
@Override
public void sendDoubleTapForTest(long timeMs, int x, int y) {}
@Override
public void onShow() {}
......
......@@ -188,13 +188,43 @@ bool EventForwarder::OnGestureEvent(JNIEnv* env,
scale, 0, 0, 0, 0, false, false));
}
void EventForwarder::OnStartFling(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jlong time_ms,
jfloat velocity_x,
jfloat velocity_y,
jboolean synthetic_scroll) {
OnCancelFling(env, jobj, time_ms);
void EventForwarder::Scroll(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jlong time_ms,
jfloat delta_x,
jfloat delta_y) {
float dip_scale = view_->GetDipScale();
float delta_xdip = delta_x / dip_scale;
float delta_ydip = delta_y / dip_scale;
view_->OnGestureEvent(GestureEventAndroid(
GESTURE_EVENT_TYPE_SCROLL_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
-delta_xdip, -delta_ydip, 0, 0, true, false));
view_->OnGestureEvent(GestureEventAndroid(
GESTURE_EVENT_TYPE_SCROLL_BY, gfx::PointF(), gfx::PointF(), time_ms, 0,
-delta_xdip, -delta_ydip, 0, 0, true, false));
view_->OnGestureEvent(GestureEventAndroid(
GESTURE_EVENT_TYPE_SCROLL_END, gfx::PointF(), gfx::PointF(), time_ms, 0,
-delta_xdip, -delta_ydip, 0, 0, true, false));
}
void EventForwarder::DoubleTap(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jlong time_ms,
jint x,
jint y) {
float dip_scale = view_->GetDipScale();
view_->OnGestureEvent(GestureEventAndroid(
GESTURE_EVENT_TYPE_DOUBLE_TAP, gfx::PointF(x / dip_scale, y / dip_scale),
gfx::PointF(), time_ms, 0, 0, 0, 0, 0, true, false));
}
void EventForwarder::StartFling(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jlong time_ms,
jfloat velocity_x,
jfloat velocity_y,
jboolean synthetic_scroll) {
CancelFling(env, jobj, time_ms);
if (velocity_x == 0 && velocity_y == 0)
return;
// Use velocity as delta in scroll event.
......@@ -206,9 +236,9 @@ void EventForwarder::OnStartFling(JNIEnv* env,
0, 0, velocity_x, velocity_y, true, synthetic_scroll));
}
void EventForwarder::OnCancelFling(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jlong time_ms) {
void EventForwarder::CancelFling(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jlong time_ms) {
view_->OnGestureEvent(
GestureEventAndroid(GESTURE_EVENT_TYPE_FLING_CANCEL, gfx::PointF(),
gfx::PointF(), time_ms, 0, 0, 0, 0, 0, false, false));
......
......@@ -90,16 +90,28 @@ class EventForwarder {
jlong time_ms,
jfloat scale);
void OnStartFling(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jlong time_ms,
jfloat velocity_x,
jfloat velocity_y,
jboolean synthetic_scroll);
void OnCancelFling(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jlong time_ms);
void Scroll(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jlong time_ms,
jfloat delta_x,
jfloat delta_y);
void DoubleTap(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jlong time_ms,
jint x,
jint y);
void StartFling(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jlong time_ms,
jfloat velocity_x,
jfloat velocity_y,
jboolean synthetic_scroll);
void CancelFling(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jlong time_ms);
private:
friend class ViewAndroid;
......
......@@ -13,6 +13,7 @@ import android.view.MotionEvent;
import android.view.View;
import org.chromium.base.TraceEvent;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
......@@ -349,6 +350,27 @@ public class EventForwarder {
return nativeOnGestureEvent(mNativeEventForwarder, type, timeMs, delta);
}
/**
* Scroll viewport by (deltaX, deltaY).
* Note: Scrolling for viewport happens in the native side. In
* the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
* are overridden so that View's mScrollX and mScrollY will stay unchanged at
* (0, 0). This is critical for drawing view correctly.
* @param timeMs the current time.
* @param velocityX fling speed in x-axis.
* @param velocityY fling speed in y-axis.
*/
public void scroll(long timeMs, float deltaX, float deltaY) {
if (mNativeEventForwarder == 0) return;
nativeScroll(mNativeEventForwarder, timeMs, deltaX, deltaY);
}
@VisibleForTesting
public void doubleTapForTest(long timeMs, int x, int y) {
if (mNativeEventForwarder == 0) return;
nativeDoubleTap(mNativeEventForwarder, timeMs, x, y);
}
/**
* Flings the viewport with velocity vector (velocityX, velocityY).
* @param timeMs the current time.
......@@ -356,19 +378,18 @@ public class EventForwarder {
* @param velocityY fling speed in y-axis.
* @param fromGamepad true if generated by gamepad (which will make this fixed-velocity fling)
*/
public void onStartFling(
long timeMs, float velocityX, float velocityY, boolean syntheticScroll) {
public void startFling(long timeMs, float velocityX, float velocityY, boolean syntheticScroll) {
if (mNativeEventForwarder == 0) return;
nativeOnStartFling(mNativeEventForwarder, timeMs, velocityX, velocityY, syntheticScroll);
nativeStartFling(mNativeEventForwarder, timeMs, velocityX, velocityY, syntheticScroll);
}
/**
* Cancel any fling gestures active.
* @param timeMs Current time (in milliseconds).
*/
public void onCancelFling(long timeMs) {
public void cancelFling(long timeMs) {
if (mNativeEventForwarder == 0) return;
nativeOnCancelFling(mNativeEventForwarder, timeMs);
nativeCancelFling(mNativeEventForwarder, timeMs);
}
private native WindowAndroid nativeGetJavaWindowAndroid(long nativeEventForwarder);
......@@ -389,7 +410,10 @@ public class EventForwarder {
int screenX, int screenY, String[] mimeTypes, String content);
private native boolean nativeOnGestureEvent(
long nativeEventForwarder, int type, long timeMs, float delta);
private native void nativeOnStartFling(long nativeEventForwarder, long timeMs, float velocityX,
private native void nativeScroll(
long nativeEventForwarder, long timeMs, float deltaX, float deltaY);
private native void nativeDoubleTap(long nativeEventForwarder, long timeMs, int x, int y);
private native void nativeStartFling(long nativeEventForwarder, long timeMs, float velocityX,
float velocityY, boolean syntheticScroll);
private native void nativeOnCancelFling(long nativeEventForwarder, long timeMs);
private native void nativeCancelFling(long nativeEventForwarder, long timeMs);
}
......@@ -1179,12 +1179,21 @@ std::unique_ptr<WebGestureEvent> CreateWebGestureEventFromGestureEventAndroid(
case GESTURE_EVENT_TYPE_SCROLL_START:
event_type = WebInputEvent::kGestureScrollBegin;
break;
case GESTURE_EVENT_TYPE_SCROLL_BY:
event_type = WebInputEvent::kGestureScrollUpdate;
break;
case GESTURE_EVENT_TYPE_SCROLL_END:
event_type = WebInputEvent::kGestureScrollEnd;
break;
case GESTURE_EVENT_TYPE_FLING_START:
event_type = WebInputEvent::kGestureFlingStart;
break;
case GESTURE_EVENT_TYPE_FLING_CANCEL:
event_type = WebInputEvent::kGestureFlingCancel;
break;
case GESTURE_EVENT_TYPE_DOUBLE_TAP:
event_type = WebInputEvent::kGestureDoubleTap;
break;
default:
NOTREACHED() << "Unknown gesture event type";
return std::make_unique<WebGestureEvent>();
......@@ -1207,6 +1216,9 @@ std::unique_ptr<WebGestureEvent> CreateWebGestureEventFromGestureEventAndroid(
web_event->data.scroll_begin.delta_x_hint = event.delta_x();
web_event->data.scroll_begin.delta_y_hint = event.delta_y();
web_event->data.scroll_begin.target_viewport = event.target_viewport();
} else if (event_type == WebInputEvent::kGestureScrollUpdate) {
web_event->data.scroll_update.delta_x = event.delta_x();
web_event->data.scroll_update.delta_y = event.delta_y();
} else if (event_type == WebInputEvent::kGestureFlingStart) {
web_event->data.fling_start.velocity_x = event.velocity_x();
web_event->data.fling_start.velocity_y = event.velocity_y();
......@@ -1215,6 +1227,11 @@ std::unique_ptr<WebGestureEvent> CreateWebGestureEventFromGestureEventAndroid(
web_event->data.fling_cancel.prevent_boosting = true;
if (event.synthetic_scroll())
web_event->data.fling_cancel.target_viewport = true;
} else if (event_type == WebInputEvent::kGestureDoubleTap) {
// Set the tap count to 1 even for DoubleTap, in order to be consistent with
// double tap behavior on a mobile viewport. See https://crbug.com/234986
// for context.
web_event->data.tap.tap_count = 1;
}
return web_event;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment