Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: content/browser/renderer_host/input/motion_event_android.cc

Issue 1417173008: Move MotionEventAndroid to ui/events/android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add OWNERS for ui/events/android Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "content/browser/renderer_host/input/motion_event_android.h"
6
7 #include <android/input.h>
8
9 #include <cmath>
10
11 #include "base/android/jni_android.h"
12 #include "jni/MotionEvent_jni.h"
13 #include "ui/events/base_event_utils.h"
14 #include "ui/events/event_constants.h"
15
16 using base::android::AttachCurrentThread;
17 using namespace JNI_MotionEvent;
18
19 namespace content {
20 namespace {
21
22 MotionEventAndroid::Action FromAndroidAction(int android_action) {
23 switch (android_action) {
24 case ACTION_DOWN:
25 return MotionEventAndroid::ACTION_DOWN;
26 case ACTION_UP:
27 return MotionEventAndroid::ACTION_UP;
28 case ACTION_MOVE:
29 return MotionEventAndroid::ACTION_MOVE;
30 case ACTION_CANCEL:
31 return MotionEventAndroid::ACTION_CANCEL;
32 case ACTION_POINTER_DOWN:
33 return MotionEventAndroid::ACTION_POINTER_DOWN;
34 case ACTION_POINTER_UP:
35 return MotionEventAndroid::ACTION_POINTER_UP;
36 default:
37 NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: "
38 << android_action;
39 };
40 return MotionEventAndroid::ACTION_CANCEL;
41 }
42
43 MotionEventAndroid::ToolType FromAndroidToolType(int android_tool_type) {
44 switch (android_tool_type) {
45 case TOOL_TYPE_UNKNOWN:
46 return MotionEventAndroid::TOOL_TYPE_UNKNOWN;
47 case TOOL_TYPE_FINGER:
48 return MotionEventAndroid::TOOL_TYPE_FINGER;
49 case TOOL_TYPE_STYLUS:
50 return MotionEventAndroid::TOOL_TYPE_STYLUS;
51 case TOOL_TYPE_MOUSE:
52 return MotionEventAndroid::TOOL_TYPE_MOUSE;
53 case TOOL_TYPE_ERASER:
54 return MotionEventAndroid::TOOL_TYPE_ERASER;
55 default:
56 NOTREACHED() << "Invalid Android MotionEvent tool type: "
57 << android_tool_type;
58 };
59 return MotionEventAndroid::TOOL_TYPE_UNKNOWN;
60 }
61
62 int FromAndroidButtonState(int button_state) {
63 int result = 0;
64 if ((button_state & BUTTON_BACK) != 0)
65 result |= MotionEventAndroid::BUTTON_BACK;
66 if ((button_state & BUTTON_FORWARD) != 0)
67 result |= MotionEventAndroid::BUTTON_FORWARD;
68 if ((button_state & BUTTON_PRIMARY) != 0)
69 result |= MotionEventAndroid::BUTTON_PRIMARY;
70 if ((button_state & BUTTON_SECONDARY) != 0)
71 result |= MotionEventAndroid::BUTTON_SECONDARY;
72 if ((button_state & BUTTON_TERTIARY) != 0)
73 result |= MotionEventAndroid::BUTTON_TERTIARY;
74 if ((button_state & BUTTON_STYLUS_PRIMARY) != 0)
75 result |= MotionEventAndroid::BUTTON_STYLUS_PRIMARY;
76 if ((button_state & BUTTON_STYLUS_SECONDARY) != 0)
77 result |= MotionEventAndroid::BUTTON_STYLUS_SECONDARY;
78 return result;
79 }
80
81 int FromAndroidMetaState(int meta_state) {
82 int flags = ui::EF_NONE;
83 if ((meta_state & AMETA_SHIFT_ON) != 0)
84 flags |= ui::EF_SHIFT_DOWN;
85 if ((meta_state & AMETA_CTRL_ON) != 0)
86 flags |= ui::EF_CONTROL_DOWN;
87 if ((meta_state & AMETA_ALT_ON) != 0)
88 flags |= ui::EF_ALT_DOWN;
89 if ((meta_state & AMETA_META_ON) != 0)
90 flags |= ui::EF_COMMAND_DOWN;
91 if ((meta_state & AMETA_CAPS_LOCK_ON) != 0)
92 flags |= ui::EF_CAPS_LOCK_DOWN;
93 return flags;
94 }
95
96 base::TimeTicks FromAndroidTime(int64 time_ms) {
97 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms);
98 }
99
100 float ToValidFloat(float x) {
101 if (std::isnan(x))
102 return 0.f;
103
104 // Wildly large orientation values have been observed in the wild after device
105 // rotation. There's not much we can do in that case other than simply
106 // sanitize results beyond an absurd and arbitrary threshold.
107 if (std::abs(x) > 1e5f)
108 return 0.f;
109
110 return x;
111 }
112
113 size_t ToValidHistorySize(jint history_size, ui::MotionEvent::Action action) {
114 DCHECK_GE(history_size, 0);
115 // While the spec states that only ACTION_MOVE events should contain
116 // historical entries, it's possible that an embedder could repurpose an
117 // ACTION_MOVE event into a different kind of event. In that case, the
118 // historical values are meaningless, and should not be exposed.
119 if (action != ui::MotionEvent::ACTION_MOVE)
120 return 0;
121 return history_size;
122 }
123
124 } // namespace
125
126 MotionEventAndroid::Pointer::Pointer(jint id,
127 jfloat pos_x_pixels,
128 jfloat pos_y_pixels,
129 jfloat touch_major_pixels,
130 jfloat touch_minor_pixels,
131 jfloat orientation_rad,
132 jfloat tilt_rad,
133 jint tool_type)
134 : id(id),
135 pos_x_pixels(pos_x_pixels),
136 pos_y_pixels(pos_y_pixels),
137 touch_major_pixels(touch_major_pixels),
138 touch_minor_pixels(touch_minor_pixels),
139 orientation_rad(orientation_rad),
140 tilt_rad(tilt_rad),
141 tool_type(tool_type) {
142 }
143
144 MotionEventAndroid::CachedPointer::CachedPointer()
145 : id(0),
146 touch_major(0),
147 touch_minor(0),
148 orientation(0),
149 tilt(0),
150 tool_type(TOOL_TYPE_UNKNOWN) {
151 }
152
153 MotionEventAndroid::MotionEventAndroid(float pix_to_dip,
154 JNIEnv* env,
155 jobject event,
156 jlong time_ms,
157 jint android_action,
158 jint pointer_count,
159 jint history_size,
160 jint action_index,
161 jint android_button_state,
162 jint meta_state,
163 jfloat raw_offset_x_pixels,
164 jfloat raw_offset_y_pixels,
165 const Pointer& pointer0,
166 const Pointer& pointer1)
167 : pix_to_dip_(pix_to_dip),
168 cached_time_(FromAndroidTime(time_ms)),
169 cached_action_(FromAndroidAction(android_action)),
170 cached_pointer_count_(pointer_count),
171 cached_history_size_(ToValidHistorySize(history_size, cached_action_)),
172 cached_action_index_(action_index),
173 cached_button_state_(FromAndroidButtonState(android_button_state)),
174 cached_flags_(FromAndroidMetaState(meta_state)),
175 cached_raw_position_offset_(ToDips(raw_offset_x_pixels),
176 ToDips(raw_offset_y_pixels)),
177 unique_event_id_(ui::GetNextTouchEventId()) {
178 DCHECK_GT(pointer_count, 0);
179
180 event_.Reset(env, event);
181 if (cached_pointer_count_ > MAX_POINTERS_TO_CACHE || cached_history_size_ > 0)
182 DCHECK(event_.obj());
183
184 cached_pointers_[0] = FromAndroidPointer(pointer0);
185 cached_pointers_[1] = FromAndroidPointer(pointer1);
186 }
187
188 MotionEventAndroid::~MotionEventAndroid() {
189 }
190
191 uint32 MotionEventAndroid::GetUniqueEventId() const {
192 return unique_event_id_;
193 }
194
195 MotionEventAndroid::Action MotionEventAndroid::GetAction() const {
196 return cached_action_;
197 }
198
199 int MotionEventAndroid::GetActionIndex() const {
200 DCHECK(cached_action_ == ACTION_POINTER_UP ||
201 cached_action_ == ACTION_POINTER_DOWN)
202 << "Invalid action for GetActionIndex(): " << cached_action_;
203 DCHECK_GE(cached_action_index_, 0);
204 DCHECK_LT(cached_action_index_, static_cast<int>(cached_pointer_count_));
205 return cached_action_index_;
206 }
207
208 size_t MotionEventAndroid::GetPointerCount() const {
209 return cached_pointer_count_;
210 }
211
212 int MotionEventAndroid::GetPointerId(size_t pointer_index) const {
213 DCHECK_LT(pointer_index, cached_pointer_count_);
214 if (pointer_index < MAX_POINTERS_TO_CACHE)
215 return cached_pointers_[pointer_index].id;
216 return Java_MotionEvent_getPointerId(
217 AttachCurrentThread(), event_.obj(), pointer_index);
218 }
219
220 float MotionEventAndroid::GetX(size_t pointer_index) const {
221 DCHECK_LT(pointer_index, cached_pointer_count_);
222 if (pointer_index < MAX_POINTERS_TO_CACHE)
223 return cached_pointers_[pointer_index].position.x();
224 return ToDips(Java_MotionEvent_getXF_I(
225 AttachCurrentThread(), event_.obj(), pointer_index));
226 }
227
228 float MotionEventAndroid::GetY(size_t pointer_index) const {
229 DCHECK_LT(pointer_index, cached_pointer_count_);
230 if (pointer_index < MAX_POINTERS_TO_CACHE)
231 return cached_pointers_[pointer_index].position.y();
232 return ToDips(Java_MotionEvent_getYF_I(
233 AttachCurrentThread(), event_.obj(), pointer_index));
234 }
235
236 float MotionEventAndroid::GetRawX(size_t pointer_index) const {
237 return GetX(pointer_index) + cached_raw_position_offset_.x();
238 }
239
240 float MotionEventAndroid::GetRawY(size_t pointer_index) const {
241 return GetY(pointer_index) + cached_raw_position_offset_.y();
242 }
243
244 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const {
245 DCHECK_LT(pointer_index, cached_pointer_count_);
246 if (pointer_index < MAX_POINTERS_TO_CACHE)
247 return cached_pointers_[pointer_index].touch_major;
248 return ToDips(Java_MotionEvent_getTouchMajorF_I(
249 AttachCurrentThread(), event_.obj(), pointer_index));
250 }
251
252 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const {
253 DCHECK_LT(pointer_index, cached_pointer_count_);
254 if (pointer_index < MAX_POINTERS_TO_CACHE)
255 return cached_pointers_[pointer_index].touch_minor;
256 return ToDips(Java_MotionEvent_getTouchMinorF_I(
257 AttachCurrentThread(), event_.obj(), pointer_index));
258 }
259
260 float MotionEventAndroid::GetOrientation(size_t pointer_index) const {
261 DCHECK_LT(pointer_index, cached_pointer_count_);
262 if (pointer_index < MAX_POINTERS_TO_CACHE)
263 return cached_pointers_[pointer_index].orientation;
264 return ToValidFloat(Java_MotionEvent_getOrientationF_I(
265 AttachCurrentThread(), event_.obj(), pointer_index));
266 }
267
268 float MotionEventAndroid::GetPressure(size_t pointer_index) const {
269 DCHECK_LT(pointer_index, cached_pointer_count_);
270 // Note that this early return is a special case exercised only in testing, as
271 // caching the pressure values is not a worthwhile optimization (they're
272 // accessed at most once per event instance).
273 if (!event_.obj())
274 return 0.f;
275 return Java_MotionEvent_getPressureF_I(
276 AttachCurrentThread(), event_.obj(), pointer_index);
277 }
278
279 float MotionEventAndroid::GetTilt(size_t pointer_index) const {
280 DCHECK_LT(pointer_index, cached_pointer_count_);
281 if (pointer_index < MAX_POINTERS_TO_CACHE)
282 return cached_pointers_[pointer_index].tilt;
283 if (!event_.obj())
284 return 0.f;
285 return ToValidFloat(Java_MotionEvent_getAxisValueF_I_I(
286 AttachCurrentThread(), event_.obj(), AXIS_TILT, pointer_index));
287 }
288
289 base::TimeTicks MotionEventAndroid::GetEventTime() const {
290 return cached_time_;
291 }
292
293 size_t MotionEventAndroid::GetHistorySize() const {
294 return cached_history_size_;
295 }
296
297 base::TimeTicks MotionEventAndroid::GetHistoricalEventTime(
298 size_t historical_index) const {
299 return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime(
300 AttachCurrentThread(), event_.obj(), historical_index));
301 }
302
303 float MotionEventAndroid::GetHistoricalTouchMajor(
304 size_t pointer_index,
305 size_t historical_index) const {
306 return ToDips(Java_MotionEvent_getHistoricalTouchMajorF_I_I(
307 AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
308 }
309
310 float MotionEventAndroid::GetHistoricalX(size_t pointer_index,
311 size_t historical_index) const {
312 return ToDips(Java_MotionEvent_getHistoricalXF_I_I(
313 AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
314 }
315
316 float MotionEventAndroid::GetHistoricalY(size_t pointer_index,
317 size_t historical_index) const {
318 return ToDips(Java_MotionEvent_getHistoricalYF_I_I(
319 AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
320 }
321
322 ui::MotionEvent::ToolType MotionEventAndroid::GetToolType(
323 size_t pointer_index) const {
324 DCHECK_LT(pointer_index, cached_pointer_count_);
325 if (pointer_index < MAX_POINTERS_TO_CACHE)
326 return cached_pointers_[pointer_index].tool_type;
327 return FromAndroidToolType(Java_MotionEvent_getToolType(
328 AttachCurrentThread(), event_.obj(), pointer_index));
329 }
330
331 int MotionEventAndroid::GetButtonState() const {
332 return cached_button_state_;
333 }
334
335 int MotionEventAndroid::GetFlags() const {
336 return cached_flags_;
337 }
338
339 float MotionEventAndroid::ToDips(float pixels) const {
340 return pixels * pix_to_dip_;
341 }
342
343 MotionEventAndroid::CachedPointer MotionEventAndroid::FromAndroidPointer(
344 const Pointer& pointer) const {
345 CachedPointer result;
346 result.id = pointer.id;
347 result.position =
348 gfx::PointF(ToDips(pointer.pos_x_pixels), ToDips(pointer.pos_y_pixels));
349 result.touch_major = ToDips(pointer.touch_major_pixels);
350 result.touch_minor = ToDips(pointer.touch_minor_pixels);
351 result.orientation = ToValidFloat(pointer.orientation_rad);
352 result.tilt = ToValidFloat(pointer.tilt_rad);
353 result.tool_type = FromAndroidToolType(pointer.tool_type);
354 return result;
355 }
356
357 // static
358 bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) {
359 return JNI_MotionEvent::RegisterNativesImpl(env);
360 }
361
362 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698