Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / renderer_host / input / motion_event_android.cc
blobc0f1721480eec0359c0b928d3516d983ceac0eb3
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.
5 #include "content/browser/renderer_host/input/motion_event_android.h"
7 #include "base/android/jni_android.h"
8 #include "jni/MotionEvent_jni.h"
10 using base::android::AttachCurrentThread;
11 using namespace JNI_MotionEvent;
13 namespace content {
14 namespace {
16 int ToAndroidAction(MotionEventAndroid::Action action) {
17 switch (action) {
18 case MotionEventAndroid::ACTION_DOWN:
19 return ACTION_DOWN;
20 case MotionEventAndroid::ACTION_UP:
21 return ACTION_UP;
22 case MotionEventAndroid::ACTION_MOVE:
23 return ACTION_MOVE;
24 case MotionEventAndroid::ACTION_CANCEL:
25 return ACTION_CANCEL;
26 case MotionEventAndroid::ACTION_POINTER_DOWN:
27 return ACTION_POINTER_DOWN;
28 case MotionEventAndroid::ACTION_POINTER_UP:
29 return ACTION_POINTER_UP;
31 NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: "
32 << action;
33 return ACTION_CANCEL;
36 MotionEventAndroid::Action FromAndroidAction(int android_action) {
37 switch (android_action) {
38 case ACTION_DOWN:
39 return MotionEventAndroid::ACTION_DOWN;
40 case ACTION_UP:
41 return MotionEventAndroid::ACTION_UP;
42 case ACTION_MOVE:
43 return MotionEventAndroid::ACTION_MOVE;
44 case ACTION_CANCEL:
45 return MotionEventAndroid::ACTION_CANCEL;
46 case ACTION_POINTER_DOWN:
47 return MotionEventAndroid::ACTION_POINTER_DOWN;
48 case ACTION_POINTER_UP:
49 return MotionEventAndroid::ACTION_POINTER_UP;
50 default:
51 NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: "
52 << android_action;
54 return MotionEventAndroid::ACTION_CANCEL;
57 int64 ToAndroidTime(base::TimeTicks time) {
58 return (time - base::TimeTicks()).InMilliseconds();
61 base::TimeTicks FromAndroidTime(int64 time_ms) {
62 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms);
65 } // namespace
67 MotionEventAndroid::MotionEventAndroid(float pix_to_dip,
68 JNIEnv* env,
69 jobject event,
70 jlong time_ms,
71 jint android_action,
72 jint pointer_count,
73 jint history_size,
74 jint action_index,
75 jfloat pos_x_0_pixels,
76 jfloat pos_y_0_pixels,
77 jfloat pos_x_1_pixels,
78 jfloat pos_y_1_pixels,
79 jint pointer_id_0,
80 jint pointer_id_1,
81 jfloat touch_major_0_pixels,
82 jfloat touch_major_1_pixels)
83 : cached_time_(FromAndroidTime(time_ms)),
84 cached_action_(FromAndroidAction(android_action)),
85 cached_pointer_count_(pointer_count),
86 cached_history_size_(history_size),
87 cached_action_index_(action_index),
88 pix_to_dip_(pix_to_dip),
89 should_recycle_(false) {
90 DCHECK_GT(pointer_count, 0);
91 DCHECK_GE(history_size, 0);
93 event_.Reset(env, event);
94 DCHECK(event_.obj());
96 cached_positions_[0] = ToDips(gfx::PointF(pos_x_0_pixels, pos_y_0_pixels));
97 cached_positions_[1] = ToDips(gfx::PointF(pos_x_1_pixels, pos_y_1_pixels));
98 cached_pointer_ids_[0] = pointer_id_0;
99 cached_pointer_ids_[1] = pointer_id_1;
100 cached_touch_majors_[0] = ToDips(touch_major_0_pixels);
101 cached_touch_majors_[1] = ToDips(touch_major_1_pixels);
104 MotionEventAndroid::MotionEventAndroid(float pix_to_dip,
105 JNIEnv* env,
106 jobject event)
107 : cached_time_(FromAndroidTime(Java_MotionEvent_getEventTime(env, event))),
108 cached_action_(
109 FromAndroidAction(Java_MotionEvent_getActionMasked(env, event))),
110 cached_pointer_count_(Java_MotionEvent_getPointerCount(env, event)),
111 cached_history_size_(Java_MotionEvent_getHistorySize(env, event)),
112 cached_action_index_(Java_MotionEvent_getActionIndex(env, event)),
113 pix_to_dip_(pix_to_dip),
114 should_recycle_(true) {
115 event_.Reset(env, event);
116 DCHECK(event_.obj());
118 for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) {
119 if (i < cached_pointer_count_) {
120 cached_positions_[i] =
121 ToDips(gfx::PointF(Java_MotionEvent_getXF_I(env, event, i),
122 Java_MotionEvent_getYF_I(env, event, i)));
123 cached_pointer_ids_[i] = Java_MotionEvent_getPointerId(env, event, i);
124 cached_touch_majors_[i] =
125 ToDips(Java_MotionEvent_getTouchMajorF_I(env, event, i));
126 } else {
127 cached_pointer_ids_[i] = 0;
128 cached_touch_majors_[i] = 0.f;
133 MotionEventAndroid::MotionEventAndroid(const MotionEventAndroid& other)
134 : event_(Obtain(other)),
135 cached_time_(other.cached_time_),
136 cached_action_(other.cached_action_),
137 cached_pointer_count_(other.cached_pointer_count_),
138 cached_history_size_(other.cached_history_size_),
139 cached_action_index_(other.cached_action_index_),
140 pix_to_dip_(other.pix_to_dip_),
141 should_recycle_(true) {
142 DCHECK(event_.obj());
143 for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) {
144 cached_positions_[i] = other.cached_positions_[i];
145 cached_pointer_ids_[i] = other.cached_pointer_ids_[i];
146 cached_touch_majors_[i] = other.cached_touch_majors_[i];
150 MotionEventAndroid::~MotionEventAndroid() {
151 if (should_recycle_)
152 Java_MotionEvent_recycle(AttachCurrentThread(), event_.obj());
155 int MotionEventAndroid::GetId() const {
156 return 0;
159 MotionEventAndroid::Action MotionEventAndroid::GetAction() const {
160 return cached_action_;
163 int MotionEventAndroid::GetActionIndex() const { return cached_action_index_; }
165 size_t MotionEventAndroid::GetPointerCount() const {
166 return cached_pointer_count_;
169 int MotionEventAndroid::GetPointerId(size_t pointer_index) const {
170 DCHECK_LT(pointer_index, cached_pointer_count_);
171 if (pointer_index < MAX_POINTERS_TO_CACHE)
172 return cached_pointer_ids_[pointer_index];
173 return Java_MotionEvent_getPointerId(
174 AttachCurrentThread(), event_.obj(), pointer_index);
177 float MotionEventAndroid::GetX(size_t pointer_index) const {
178 DCHECK_LT(pointer_index, cached_pointer_count_);
179 if (pointer_index < MAX_POINTERS_TO_CACHE)
180 return cached_positions_[pointer_index].x();
181 return ToDips(Java_MotionEvent_getXF_I(
182 AttachCurrentThread(), event_.obj(), pointer_index));
185 float MotionEventAndroid::GetY(size_t pointer_index) const {
186 DCHECK_LT(pointer_index, cached_pointer_count_);
187 if (pointer_index < MAX_POINTERS_TO_CACHE)
188 return cached_positions_[pointer_index].y();
189 return ToDips(Java_MotionEvent_getYF_I(
190 AttachCurrentThread(), event_.obj(), pointer_index));
193 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const {
194 DCHECK_LT(pointer_index, cached_pointer_count_);
195 if (pointer_index < MAX_POINTERS_TO_CACHE)
196 return cached_touch_majors_[pointer_index];
197 return ToDips(Java_MotionEvent_getTouchMajorF_I(
198 AttachCurrentThread(), event_.obj(), pointer_index));
201 float MotionEventAndroid::GetPressure(size_t pointer_index) const {
202 DCHECK_LT(pointer_index, cached_pointer_count_);
203 return Java_MotionEvent_getPressureF_I(
204 AttachCurrentThread(), event_.obj(), pointer_index);
207 base::TimeTicks MotionEventAndroid::GetEventTime() const {
208 return cached_time_;
211 size_t MotionEventAndroid::GetHistorySize() const {
212 return cached_history_size_;
215 base::TimeTicks MotionEventAndroid::GetHistoricalEventTime(
216 size_t historical_index) const {
217 return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime(
218 AttachCurrentThread(), event_.obj(), historical_index));
221 float MotionEventAndroid::GetHistoricalTouchMajor(
222 size_t pointer_index,
223 size_t historical_index) const {
224 return ToDips(Java_MotionEvent_getHistoricalTouchMajorF_I_I(
225 AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
228 float MotionEventAndroid::GetHistoricalX(size_t pointer_index,
229 size_t historical_index) const {
230 return ToDips(Java_MotionEvent_getHistoricalXF_I_I(
231 AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
234 float MotionEventAndroid::GetHistoricalY(size_t pointer_index,
235 size_t historical_index) const {
236 return ToDips(Java_MotionEvent_getHistoricalYF_I_I(
237 AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
240 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Clone() const {
241 return scoped_ptr<MotionEvent>(new MotionEventAndroid(*this));
244 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Cancel() const {
245 // The input coordinates to |MotionEventAndroid| are always in device pixels,
246 // but the cached coordinates are in DIPs.
247 const gfx::PointF position_pixels =
248 gfx::ScalePoint(cached_positions_[0], 1.f / pix_to_dip_);
249 return scoped_ptr<MotionEvent>(
250 new MotionEventAndroid(pix_to_dip_,
251 AttachCurrentThread(),
252 Obtain(GetDownTime(),
253 GetEventTime(),
254 MotionEventAndroid::ACTION_CANCEL,
255 position_pixels.x(),
256 position_pixels.y()).obj()));
259 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const {
260 return ToDips(Java_MotionEvent_getTouchMinorF_I(
261 AttachCurrentThread(), event_.obj(), pointer_index));
264 float MotionEventAndroid::GetOrientation() const {
265 return Java_MotionEvent_getOrientationF(AttachCurrentThread(), event_.obj());
268 base::TimeTicks MotionEventAndroid::GetDownTime() const {
269 return FromAndroidTime(
270 Java_MotionEvent_getDownTime(AttachCurrentThread(), event_.obj()));
273 float MotionEventAndroid::ToDips(float pixels) const {
274 return pixels * pix_to_dip_;
277 gfx::PointF MotionEventAndroid::ToDips(const gfx::PointF& point_pixels) const {
278 return gfx::ScalePoint(point_pixels, pix_to_dip_);
281 // static
282 bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) {
283 return JNI_MotionEvent::RegisterNativesImpl(env);
286 // static
287 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain(
288 const MotionEventAndroid& event) {
289 return Java_MotionEvent_obtainAVME_AVME(AttachCurrentThread(),
290 event.event_.obj());
293 // static
294 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain(
295 base::TimeTicks down_time,
296 base::TimeTicks event_time,
297 Action action,
298 float x_pixels,
299 float y_pixels) {
300 return Java_MotionEvent_obtainAVME_J_J_I_F_F_I(AttachCurrentThread(),
301 ToAndroidTime(down_time),
302 ToAndroidTime(event_time),
303 ToAndroidAction(action),
304 x_pixels,
305 y_pixels,
309 } // namespace content