[InputVizard] Transfer web contents offset added to Browser as is.
In current implementation on Viz side, web contents offset was being recalculated on Viz side again using GetY, GetRawY and the raw offset of point on Browser side. With this change we are transferring the offset as is to Viz instead of recalculating it separately for each event. This would be inline with Browser side behavior as well where the offset could only get changed on down events. Bug: 401233890 Change-Id: I0532d1b0ead3870fceb25edc32e7dafb8e8508f3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6368256 Commit-Queue: Kartar Singh <kartarsingh@google.com> Reviewed-by: Jonathan Ross <jonross@chromium.org> Reviewed-by: Dave Tapuska <dtapuska@chromium.org> Reviewed-by: Colin Blundell <blundell@chromium.org> Reviewed-by: Mike West <mkwst@chromium.org> Cr-Commit-Position: refs/heads/main@{#1436075}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
3d6d573c4e
commit
48fb0a79fe
components
input
viz
content/browser
renderer_host
web_contents
ui
android
events
@ -37,10 +37,10 @@ struct TouchTransferState {
|
||||
// FrameSinkId of root widget which was being touched at the time of transfer.
|
||||
viz.mojom.FrameSinkId root_widget_frame_sink_id;
|
||||
|
||||
// Raw y offset added to raw screen coordinates to get coordinates relative to
|
||||
// root widget. This will be used to account for top controls height when
|
||||
// creating MotionEventAndroid on Viz side.
|
||||
int32 raw_y_offset;
|
||||
// Y offset to be added to points received from Android to get coordinates
|
||||
// relative to root widget. This will be used to account for top controls
|
||||
// height when creating MotionEventAndroid on Viz side.
|
||||
float web_contents_y_offset_pix;
|
||||
|
||||
// Device scale factor being used to create MotionEventAndroid objects for
|
||||
// converting device pixels to device independent pixels.
|
||||
|
@ -226,19 +226,10 @@ void AndroidStateTransferHandler::HandleTouchEvent(
|
||||
return;
|
||||
}
|
||||
|
||||
const float viz_y_offset_pix =
|
||||
AMotionEvent_getY(input_event.a_input_event(), /*pointer_index=*/0) -
|
||||
AMotionEvent_getRawY(input_event.a_input_event(), /*pointer_index=*/0);
|
||||
// Offset added to points in Android's view coordinate system to convert them
|
||||
// into coordinates relative to web contents. This is used to accommodate for
|
||||
// browser top controls when visible.
|
||||
const float web_contents_y_offset_pix =
|
||||
state_for_curr_sequence_->transfer_state->raw_y_offset - viz_y_offset_pix;
|
||||
CHECK_LE(web_contents_y_offset_pix, 0);
|
||||
auto event = ui::MotionEventAndroidNative::Create(
|
||||
std::move(input_event),
|
||||
1.f / state_for_curr_sequence_->transfer_state->dip_scale,
|
||||
web_contents_y_offset_pix);
|
||||
state_for_curr_sequence_->transfer_state->web_contents_y_offset_pix);
|
||||
|
||||
state_for_curr_sequence_->rir_support->OnTouchEvent(
|
||||
*event.get(), /* emit_histograms= */ true);
|
||||
|
@ -462,18 +462,33 @@ TEST_F(AndroidStateTransferHandlerTest, UsesDeviceScaleFactorFromState) {
|
||||
}
|
||||
}
|
||||
|
||||
// _______________________
|
||||
// | (sys_ui_offset) |
|
||||
// |-----------------------|
|
||||
// | (web_contents_offset) |
|
||||
// |-----------------------|
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// |-----------------------|
|
||||
//
|
||||
TEST_F(AndroidStateTransferHandlerTest,
|
||||
UsesWebContentsOffsetForMotionEventCreation) {
|
||||
const int android_raw_offset = -9;
|
||||
int sys_ui_offset = -9;
|
||||
const int web_contents_offset = -8;
|
||||
const int raw_y = 109;
|
||||
const int delta_x = 0;
|
||||
const int meta_state = 0;
|
||||
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
base::android::ScopedJavaLocalRef<jobject> java_motion_event =
|
||||
JNI_MotionEvent::Java_MotionEvent_obtain(env, 0, 0, kAndroidActionDown, 0,
|
||||
raw_y, meta_state);
|
||||
JNI_MotionEvent::Java_MotionEvent_offsetLocation(env, java_motion_event,
|
||||
delta_x, android_raw_offset);
|
||||
delta_x, sys_ui_offset);
|
||||
|
||||
const AInputEvent* native_event = nullptr;
|
||||
if (__builtin_available(android 31, *)) {
|
||||
@ -481,17 +496,35 @@ TEST_F(AndroidStateTransferHandlerTest,
|
||||
}
|
||||
CHECK(native_event);
|
||||
|
||||
const int web_contents_offset_pix = -8;
|
||||
const int browser_y_offset_pix = android_raw_offset + web_contents_offset_pix;
|
||||
const int expected_y = raw_y + browser_y_offset_pix;
|
||||
|
||||
auto state = input::mojom::TouchTransferState::New();
|
||||
state->dip_scale = 1.f;
|
||||
state->raw_y_offset = browser_y_offset_pix;
|
||||
state->web_contents_y_offset_pix = web_contents_offset;
|
||||
|
||||
handler_.StateOnTouchTransfer(std::move(state),
|
||||
mock_rir_support_.GetWeakPtr());
|
||||
|
||||
int expected_y = raw_y + sys_ui_offset + web_contents_offset;
|
||||
EXPECT_CALL(mock_rir_support_, OnTouchEvent(EqXYInPixels(0, expected_y), _));
|
||||
handler_.OnMotionEvent(base::android::ScopedInputEvent(native_event),
|
||||
kRootCompositorFrameSinkId);
|
||||
|
||||
// Offset by an arbitrary value which is larger than absolute value of
|
||||
// `web_contents_offset`.
|
||||
sys_ui_offset -= 10;
|
||||
base::android::ScopedJavaLocalRef<jobject>
|
||||
motion_event_with_diff_sys_ui_offset =
|
||||
JNI_MotionEvent::Java_MotionEvent_obtain(
|
||||
env, 0, 0, kAndroidActionMove, 0, raw_y, meta_state);
|
||||
JNI_MotionEvent::Java_MotionEvent_offsetLocation(
|
||||
env, motion_event_with_diff_sys_ui_offset, delta_x, sys_ui_offset);
|
||||
|
||||
if (__builtin_available(android 31, *)) {
|
||||
native_event =
|
||||
AMotionEvent_fromJava(env, motion_event_with_diff_sys_ui_offset.obj());
|
||||
}
|
||||
CHECK(native_event);
|
||||
|
||||
expected_y = raw_y + sys_ui_offset + web_contents_offset;
|
||||
EXPECT_CALL(mock_rir_support_, OnTouchEvent(EqXYInPixels(0, expected_y), _));
|
||||
handler_.OnMotionEvent(base::android::ScopedInputEvent(native_event),
|
||||
kRootCompositorFrameSinkId);
|
||||
|
@ -192,4 +192,10 @@ RenderWidgetHostDelegate::GetRenderInputRouterDelegateRemote() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
float RenderWidgetHostDelegate::GetCurrentTouchSequenceYOffset() {
|
||||
return 0.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace content
|
||||
|
@ -378,6 +378,13 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
|
||||
virtual input::mojom::RenderInputRouterDelegate*
|
||||
GetRenderInputRouterDelegateRemote();
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
// Get the y value by which the touch sequence is offsetted by. For e.g.
|
||||
// visible top controls will result in a non zero offset to be added to touch
|
||||
// events.
|
||||
virtual float GetCurrentTouchSequenceYOffset();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~RenderWidgetHostDelegate() {}
|
||||
};
|
||||
|
@ -1329,10 +1329,8 @@ void RenderWidgetHostViewAndroid::SendStateOnTouchTransfer(
|
||||
TRACE_EVENT("input", "RenderWidgetHostViewAndroid::StateOnTouchTransfer");
|
||||
CHECK(host());
|
||||
auto* remote = host()->delegate()->GetRenderInputRouterDelegateRemote();
|
||||
// Negate the offset. The calculation usually looks like this:
|
||||
// `GetRayY + offset = GetY`. But MotionEvent returns the offset as GetRawY -
|
||||
// GetY.
|
||||
int y_offset_pix = -(std::round(event.GetRawOffsetY() * view_.GetDipScale()));
|
||||
const float y_offset_pix =
|
||||
host()->delegate()->GetCurrentTouchSequenceYOffset();
|
||||
remote->StateOnTouchTransfer(input::mojom::TouchTransferState::New(
|
||||
event.GetDownTime(), GetFrameSinkId(), y_offset_pix, view_.GetDipScale(),
|
||||
browser_would_have_handled));
|
||||
|
@ -235,6 +235,7 @@
|
||||
#include "content/browser/web_contents/web_contents_view_android.h"
|
||||
#include "services/device/public/mojom/nfc.mojom.h"
|
||||
#include "services/service_manager/public/cpp/interface_provider.h"
|
||||
#include "ui/android/event_forwarder.h"
|
||||
#include "ui/android/view_android.h"
|
||||
#include "ui/base/device_form_factor.h"
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
@ -11715,6 +11716,13 @@ WebContentsImpl::GetRenderInputRouterDelegateRemote() {
|
||||
return rir_delegate_remote_.get();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
float WebContentsImpl::GetCurrentTouchSequenceYOffset() {
|
||||
ui::ViewAndroid* view_android = GetNativeView();
|
||||
return view_android->event_forwarder()->GetCurrentTouchSequenceYOffset();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<PrefetchHandle> WebContentsImpl::StartPrefetch(
|
||||
const GURL& prefetch_url,
|
||||
bool use_prefetch_proxy,
|
||||
|
@ -1189,6 +1189,9 @@ class CONTENT_EXPORT WebContentsImpl
|
||||
void OnInputIgnored(const blink::WebInputEvent& event) override;
|
||||
input::mojom::RenderInputRouterDelegate* GetRenderInputRouterDelegateRemote()
|
||||
override;
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
float GetCurrentTouchSequenceYOffset() override;
|
||||
#endif
|
||||
|
||||
// RenderFrameHostManager::Delegate ------------------------------------------
|
||||
|
||||
|
@ -328,4 +328,10 @@ void EventForwarder::RemoveObserver(Observer* observer) {
|
||||
observers_.RemoveObserver(observer);
|
||||
}
|
||||
|
||||
float EventForwarder::GetCurrentTouchSequenceYOffset() {
|
||||
CHECK(!java_obj_.is_null());
|
||||
JNIEnv* env = jni_zero::AttachCurrentThread();
|
||||
return Java_EventForwarder_getWebContentsOffsetYInWindow(env, java_obj_);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -163,6 +163,8 @@ class UI_ANDROID_EXPORT EventForwarder {
|
||||
|
||||
void RemoveObserver(Observer* observer);
|
||||
|
||||
float GetCurrentTouchSequenceYOffset();
|
||||
|
||||
private:
|
||||
friend class ViewAndroid;
|
||||
|
||||
|
@ -214,6 +214,11 @@ public class EventForwarder {
|
||||
return false;
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
private float getWebContentsOffsetYInWindow() {
|
||||
return mCurrentTouchOffsetY;
|
||||
}
|
||||
|
||||
private boolean sendTouchEvent(MotionEvent event, boolean isTouchHandleEvent) {
|
||||
assert mNativeEventForwarder != 0;
|
||||
|
||||
|
@ -51,7 +51,7 @@ MotionEventAndroidNative::MotionEventAndroidNative(
|
||||
bool for_touch_handle,
|
||||
const Pointer* const pointer0,
|
||||
const Pointer* const pointer1,
|
||||
int y_offset_pix)
|
||||
float y_offset_pix)
|
||||
: MotionEventAndroid(pix_to_dip,
|
||||
ticks_x,
|
||||
ticks_y,
|
||||
@ -82,7 +82,7 @@ MotionEventAndroidNative::MotionEventAndroidNative(
|
||||
std::unique_ptr<MotionEventAndroid> MotionEventAndroidNative::Create(
|
||||
base::android::ScopedInputEvent input_event,
|
||||
float pix_to_dip,
|
||||
int y_offset_pix) {
|
||||
float y_offset_pix) {
|
||||
const AInputEvent* event = input_event.a_input_event();
|
||||
|
||||
CHECK(event != nullptr);
|
||||
|
@ -60,7 +60,7 @@ class EVENTS_EXPORT MotionEventAndroidNative : public MotionEventAndroid {
|
||||
static std::unique_ptr<MotionEventAndroid> Create(
|
||||
base::android::ScopedInputEvent input_event,
|
||||
float pix_to_dip,
|
||||
int y_offset_pix);
|
||||
float y_offset_pix);
|
||||
|
||||
private:
|
||||
MotionEventAndroidNative(base::android::ScopedInputEvent input_event,
|
||||
@ -85,11 +85,11 @@ class EVENTS_EXPORT MotionEventAndroidNative : public MotionEventAndroid {
|
||||
bool for_touch_handle,
|
||||
const Pointer* const pointer0,
|
||||
const Pointer* const pointer1,
|
||||
int y_offset);
|
||||
float y_offset_pix);
|
||||
|
||||
const base::android::ScopedInputEvent native_event_;
|
||||
// Amount of value to offset Y axis values by to accommodate for top controls.
|
||||
int y_offset_pix_;
|
||||
float y_offset_pix_;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
Reference in New Issue
Block a user