blob: cd3643cbe37dd33813da2ed296186cc542aca780 [file] [log] [blame]
jinsukkim5c3a1202017-03-10 00:02:141// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/android/event_forwarder.h"
6
jinsukkimda11b4d2017-05-26 06:44:417#include "base/android/jni_array.h"
Andrew Grieve4a42c22e2019-06-24 16:14:298#include "ui/android/ui_android_jni_headers/EventForwarder_jni.h"
Michael Thiessene70dd08d2017-12-21 20:59:119#include "ui/android/window_android.h"
jinsukkimda11b4d2017-05-26 06:44:4110#include "ui/base/ui_base_switches_util.h"
11#include "ui/events/android/drag_event_android.h"
Jinsuk Kim63626ce42017-11-23 06:19:5612#include "ui/events/android/gesture_event_android.h"
Jinsuk Kime6c2eafb2018-02-23 01:10:3613#include "ui/events/android/gesture_event_type.h"
Jinsuk Kim5a3ae93c2018-04-25 21:49:0614#include "ui/events/android/key_event_android.h"
jinsukkim5c3a1202017-03-10 00:02:1415#include "ui/events/android/motion_event_android.h"
16
17namespace ui {
18
jinsukkimda11b4d2017-05-26 06:44:4119using base::android::AppendJavaStringArrayToStringVector;
jinsukkim5c3a1202017-03-10 00:02:1420using base::android::JavaParamRef;
21using base::android::ScopedJavaLocalRef;
22
23EventForwarder::EventForwarder(ViewAndroid* view) : view_(view) {}
24
25EventForwarder::~EventForwarder() {
26 if (!java_obj_.is_null()) {
27 Java_EventForwarder_destroy(base::android::AttachCurrentThread(),
28 java_obj_);
29 java_obj_.Reset();
30 }
31}
32
33ScopedJavaLocalRef<jobject> EventForwarder::GetJavaObject() {
34 if (java_obj_.is_null()) {
jinsukkimda11b4d2017-05-26 06:44:4135 JNIEnv* env = base::android::AttachCurrentThread();
jinsukkim5c3a1202017-03-10 00:02:1436 java_obj_.Reset(
jinsukkimda11b4d2017-05-26 06:44:4137 Java_EventForwarder_create(env, reinterpret_cast<intptr_t>(this),
38 switches::IsTouchDragDropEnabled()));
jinsukkim5c3a1202017-03-10 00:02:1439 }
40 return ScopedJavaLocalRef<jobject>(java_obj_);
41}
42
Michael Thiessene70dd08d2017-12-21 20:59:1143ScopedJavaLocalRef<jobject> EventForwarder::GetJavaWindowAndroid(
44 JNIEnv* env,
45 const JavaParamRef<jobject>& obj) {
46 return view_->GetWindowAndroid()->GetJavaObject();
47}
48
jinsukkim5c3a1202017-03-10 00:02:1449jboolean EventForwarder::OnTouchEvent(JNIEnv* env,
50 const JavaParamRef<jobject>& obj,
51 const JavaParamRef<jobject>& motion_event,
52 jlong time_ms,
53 jint android_action,
54 jint pointer_count,
55 jint history_size,
56 jint action_index,
57 jfloat pos_x_0,
58 jfloat pos_y_0,
59 jfloat pos_x_1,
60 jfloat pos_y_1,
61 jint pointer_id_0,
62 jint pointer_id_1,
63 jfloat touch_major_0,
64 jfloat touch_major_1,
65 jfloat touch_minor_0,
66 jfloat touch_minor_1,
67 jfloat orientation_0,
68 jfloat orientation_1,
69 jfloat tilt_0,
70 jfloat tilt_1,
71 jfloat raw_pos_x,
72 jfloat raw_pos_y,
73 jint android_tool_type_0,
74 jint android_tool_type_1,
75 jint android_button_state,
76 jint android_meta_state,
Jinsuk Kim2b859472017-08-30 02:47:1977 jboolean for_touch_handle) {
jinsukkim5c3a1202017-03-10 00:02:1478 ui::MotionEventAndroid::Pointer pointer0(
79 pointer_id_0, pos_x_0, pos_y_0, touch_major_0, touch_minor_0,
80 orientation_0, tilt_0, android_tool_type_0);
81 ui::MotionEventAndroid::Pointer pointer1(
82 pointer_id_1, pos_x_1, pos_y_1, touch_major_1, touch_minor_1,
83 orientation_1, tilt_1, android_tool_type_1);
84 ui::MotionEventAndroid event(
jinsukkimb40b402c2017-03-29 09:39:0885 env, motion_event.obj(), 1.f / view_->GetDipScale(), 0.f, 0.f, 0.f,
86 time_ms, android_action, pointer_count, history_size, action_index,
jinsukkim5c3a1202017-03-10 00:02:1487 0 /* action_button */, android_button_state, android_meta_state,
Jinsuk Kim2b859472017-08-30 02:47:1988 raw_pos_x - pos_x_0, raw_pos_y - pos_y_0, for_touch_handle, &pointer0,
89 &pointer1);
90 return view_->OnTouchEvent(event);
jinsukkim5c3a1202017-03-10 00:02:1491}
92
93void EventForwarder::OnMouseEvent(JNIEnv* env,
94 const JavaParamRef<jobject>& obj,
95 jlong time_ms,
96 jint android_action,
97 jfloat x,
98 jfloat y,
99 jint pointer_id,
100 jfloat orientation,
101 jfloat pressure,
102 jfloat tilt,
103 jint android_action_button,
104 jint android_button_state,
105 jint android_meta_state,
106 jint android_tool_type) {
107 // Construct a motion_event object minimally, only to convert the raw
108 // parameters to ui::MotionEvent values. Since we used only the cached values
109 // at index=0, it is okay to even pass a null event to the constructor.
110 ui::MotionEventAndroid::Pointer pointer(
111 pointer_id, x, y, 0.0f /* touch_major */, 0.0f /* touch_minor */,
112 orientation, tilt, android_tool_type);
113 ui::MotionEventAndroid event(
jinsukkimb40b402c2017-03-29 09:39:08114 env, nullptr /* event */, 1.f / view_->GetDipScale(), 0.f, 0.f, 0.f,
115 time_ms, android_action, 1 /* pointer_count */, 0 /* history_size */,
jinsukkim5c3a1202017-03-10 00:02:14116 0 /* action_index */, android_action_button, android_button_state,
117 android_meta_state, 0 /* raw_offset_x_pixels */,
Jinsuk Kim2b859472017-08-30 02:47:19118 0 /* raw_offset_y_pixels */, false /* for_touch_handle */, &pointer,
119 nullptr);
jinsukkim5c3a1202017-03-10 00:02:14120 view_->OnMouseEvent(event);
121}
122
jinsukkimda11b4d2017-05-26 06:44:41123void EventForwarder::OnDragEvent(JNIEnv* env,
124 const JavaParamRef<jobject>& jobj,
125 jint action,
126 jint x,
127 jint y,
128 jint screen_x,
129 jint screen_y,
130 const JavaParamRef<jobjectArray>& j_mimeTypes,
131 const JavaParamRef<jstring>& j_content) {
132 float dip_scale = view_->GetDipScale();
133 gfx::PointF location(x / dip_scale, y / dip_scale);
134 gfx::PointF root_location(screen_x / dip_scale, screen_y / dip_scale);
135 std::vector<base::string16> mime_types;
136 AppendJavaStringArrayToStringVector(env, j_mimeTypes, &mime_types);
137
138 DragEventAndroid event(env, action, location, root_location, mime_types,
139 j_content.obj());
140 view_->OnDragEvent(event);
141}
142
Jinsuk Kim5a3ae93c2018-04-25 21:49:06143jboolean EventForwarder::OnGestureEvent(JNIEnv* env,
144 const JavaParamRef<jobject>& jobj,
145 jint type,
146 jlong time_ms,
147 jfloat scale) {
Jinsuk Kim63626ce42017-11-23 06:19:56148 float dip_scale = view_->GetDipScale();
149 auto size = view_->GetSize();
150 float x = size.width() / 2;
151 float y = size.height() / 2;
152 gfx::PointF root_location =
153 ScalePoint(view_->GetLocationOnScreen(x, y), 1.f / dip_scale);
Jinsuk Kime6c2eafb2018-02-23 01:10:36154 return view_->OnGestureEvent(GestureEventAndroid(
155 type, gfx::PointF(x / dip_scale, y / dip_scale), root_location, time_ms,
David Bokan4b32e5d12018-07-09 02:11:59156 scale, 0, 0, 0, 0, /*target_viewport*/ false, /*synthetic_scroll*/ false,
157 /*prevent_boosting*/ false));
Jinsuk Kime6c2eafb2018-02-23 01:10:36158}
159
Jinsuk Kim7ba8f2402018-05-04 20:44:36160jboolean EventForwarder::OnGenericMotionEvent(
161 JNIEnv* env,
162 const JavaParamRef<jobject>& obj,
163 const JavaParamRef<jobject>& motion_event,
164 jlong time_ms) {
165 auto size = view_->GetSize();
166 float x = size.width() / 2;
167 float y = size.height() / 2;
168 ui::MotionEventAndroid::Pointer pointer0(0, x, y, 0, 0, 0, 0, 0);
169 ui::MotionEventAndroid event(
170 env, motion_event.obj(), 1.f / view_->GetDipScale(), 0.f, 0.f, 0.f,
171 time_ms, 0, 1, 0, 0, 0, 0, 0, 0, 0, false, &pointer0, nullptr);
172 return view_->OnGenericMotionEvent(event);
173}
174
Jinsuk Kim5a3ae93c2018-04-25 21:49:06175jboolean EventForwarder::OnKeyUp(JNIEnv* env,
176 const JavaParamRef<jobject>& obj,
177 const JavaParamRef<jobject>& key_event,
178 jint key_code) {
179 return view_->OnKeyUp(KeyEventAndroid(env, key_event, key_code));
180}
181
182jboolean EventForwarder::DispatchKeyEvent(
183 JNIEnv* env,
184 const JavaParamRef<jobject>& obj,
185 const JavaParamRef<jobject>& key_event) {
186 return view_->DispatchKeyEvent(KeyEventAndroid(env, key_event, 0));
187}
188
Jinsuk Kim7ba8f2402018-05-04 20:44:36189void EventForwarder::ScrollBy(JNIEnv* env,
190 const JavaParamRef<jobject>& jobj,
191 jfloat delta_x,
192 jfloat delta_y) {
193 view_->ScrollBy(delta_x, delta_y);
194}
195
196void EventForwarder::ScrollTo(JNIEnv* env,
197 const JavaParamRef<jobject>& jobj,
198 jfloat x,
199 jfloat y) {
200 view_->ScrollTo(x, y);
Jinsuk Kim78627332018-03-05 23:33:39201}
202
203void EventForwarder::DoubleTap(JNIEnv* env,
204 const JavaParamRef<jobject>& jobj,
205 jlong time_ms,
206 jint x,
207 jint y) {
208 float dip_scale = view_->GetDipScale();
209 view_->OnGestureEvent(GestureEventAndroid(
210 GESTURE_EVENT_TYPE_DOUBLE_TAP, gfx::PointF(x / dip_scale, y / dip_scale),
David Bokan4b32e5d12018-07-09 02:11:59211 gfx::PointF(), time_ms, 0, 0, 0, 0, 0, /*target_viewport*/ true,
212 /*synthetic_scroll*/ false, /*prevent_boosting*/ false));
Jinsuk Kim78627332018-03-05 23:33:39213}
214
215void EventForwarder::StartFling(JNIEnv* env,
216 const JavaParamRef<jobject>& jobj,
217 jlong time_ms,
218 jfloat velocity_x,
219 jfloat velocity_y,
David Bokan4b32e5d12018-07-09 02:11:59220 jboolean synthetic_scroll,
221 jboolean prevent_boosting) {
222 CancelFling(env, jobj, time_ms, prevent_boosting);
223
Jinsuk Kime6c2eafb2018-02-23 01:10:36224 if (velocity_x == 0 && velocity_y == 0)
225 return;
Ella Geb1b87222019-04-02 17:19:50226 float dip_scale = view_->GetDipScale();
Jinsuk Kime6c2eafb2018-02-23 01:10:36227 // Use velocity as delta in scroll event.
228 view_->OnGestureEvent(GestureEventAndroid(
229 GESTURE_EVENT_TYPE_SCROLL_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
Ella Geb1b87222019-04-02 17:19:50230 velocity_x / dip_scale, velocity_y / dip_scale, 0, 0,
231 /*target_viewport*/ true, synthetic_scroll,
David Bokan4b32e5d12018-07-09 02:11:59232 /*prevent_boosting*/ false));
Jinsuk Kime6c2eafb2018-02-23 01:10:36233 view_->OnGestureEvent(GestureEventAndroid(
234 GESTURE_EVENT_TYPE_FLING_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
Ella Geb1b87222019-04-02 17:19:50235 0, 0, velocity_x / dip_scale, velocity_y / dip_scale,
236 /*target_viewport*/ true, synthetic_scroll,
David Bokan4b32e5d12018-07-09 02:11:59237 /*prevent_boosting*/ false));
Jinsuk Kime6c2eafb2018-02-23 01:10:36238}
239
Jinsuk Kim78627332018-03-05 23:33:39240void EventForwarder::CancelFling(JNIEnv* env,
241 const JavaParamRef<jobject>& jobj,
David Bokan4b32e5d12018-07-09 02:11:59242 jlong time_ms,
243 jboolean prevent_boosting) {
244 view_->OnGestureEvent(GestureEventAndroid(
245 GESTURE_EVENT_TYPE_FLING_CANCEL, gfx::PointF(), gfx::PointF(), time_ms, 0,
246 0, 0, 0, 0,
247 /*target_viewport*/ false, /*synthetic_scroll*/ false, prevent_boosting));
Jinsuk Kim63626ce42017-11-23 06:19:56248}
249
jinsukkim5c3a1202017-03-10 00:02:14250} // namespace ui