OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/input/motion_event_android.h" | 5 #include "content/browser/renderer_host/input/motion_event_android.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "jni/MotionEvent_jni.h" | 8 #include "jni/MotionEvent_jni.h" |
9 | 9 |
10 using base::android::AttachCurrentThread; | 10 using base::android::AttachCurrentThread; |
11 using namespace JNI_MotionEvent; | 11 using namespace JNI_MotionEvent; |
12 | 12 |
13 namespace content { | 13 namespace content { |
14 namespace { | 14 namespace { |
15 | 15 |
| 16 // Note: These constants are taken directly from android.view.MotionEvent. |
| 17 // Do NOT under any circumstances change these values. |
| 18 enum AndroidMotionEventAction { |
| 19 ANDROID_ACTION_DOWN = 0, |
| 20 ANDROID_ACTION_UP = 1, |
| 21 ANDROID_ACTION_MOVE = 2, |
| 22 ANDROID_ACTION_CANCEL = 3, |
| 23 // Purposefully removed, as there is no analogous action in Chromium. |
| 24 // ANDROID_ACTION_OUTSIDE = 4, |
| 25 ANDROID_ACTION_POINTER_DOWN = 5, |
| 26 ANDROID_ACTION_POINTER_UP = 6 |
| 27 }; |
| 28 |
| 29 AndroidMotionEventAction ToAndroidAction(MotionEventAndroid::Action action) { |
| 30 switch (action) { |
| 31 case MotionEventAndroid::ACTION_DOWN: |
| 32 return ANDROID_ACTION_DOWN; |
| 33 case MotionEventAndroid::ACTION_UP: |
| 34 return ANDROID_ACTION_UP; |
| 35 case MotionEventAndroid::ACTION_MOVE: |
| 36 return ANDROID_ACTION_MOVE; |
| 37 case MotionEventAndroid::ACTION_CANCEL: |
| 38 return ANDROID_ACTION_CANCEL; |
| 39 case MotionEventAndroid::ACTION_POINTER_DOWN: |
| 40 return ANDROID_ACTION_POINTER_DOWN; |
| 41 case MotionEventAndroid::ACTION_POINTER_UP: |
| 42 return ANDROID_ACTION_POINTER_UP; |
| 43 }; |
| 44 NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: " |
| 45 << action; |
| 46 return ANDROID_ACTION_CANCEL; |
| 47 } |
| 48 |
16 MotionEventAndroid::Action FromAndroidAction(int android_action) { | 49 MotionEventAndroid::Action FromAndroidAction(int android_action) { |
17 switch (android_action) { | 50 switch (android_action) { |
18 case MotionEventAndroid::ACTION_DOWN: | 51 case ANDROID_ACTION_DOWN: |
19 case MotionEventAndroid::ACTION_UP: | 52 return MotionEventAndroid::ACTION_DOWN; |
20 case MotionEventAndroid::ACTION_MOVE: | 53 case ANDROID_ACTION_UP: |
21 case MotionEventAndroid::ACTION_CANCEL: | 54 return MotionEventAndroid::ACTION_UP; |
22 case MotionEventAndroid::ACTION_POINTER_DOWN: | 55 case ANDROID_ACTION_MOVE: |
23 case MotionEventAndroid::ACTION_POINTER_UP: | 56 return MotionEventAndroid::ACTION_MOVE; |
24 return static_cast<MotionEventAndroid::Action>(android_action); | 57 case ANDROID_ACTION_CANCEL: |
| 58 return MotionEventAndroid::ACTION_CANCEL; |
| 59 case ANDROID_ACTION_POINTER_DOWN: |
| 60 return MotionEventAndroid::ACTION_POINTER_DOWN; |
| 61 case ANDROID_ACTION_POINTER_UP: |
| 62 return MotionEventAndroid::ACTION_POINTER_UP; |
25 default: | 63 default: |
26 NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: " | 64 NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: " |
27 << android_action; | 65 << android_action; |
28 }; | 66 }; |
29 return MotionEventAndroid::ACTION_CANCEL; | 67 return MotionEventAndroid::ACTION_CANCEL; |
30 } | 68 } |
31 | 69 |
32 int64 ToAndroidTime(base::TimeTicks time) { | 70 int64 ToAndroidTime(base::TimeTicks time) { |
33 return (time - base::TimeTicks()).InMilliseconds(); | 71 return (time - base::TimeTicks()).InMilliseconds(); |
34 } | 72 } |
35 | 73 |
36 base::TimeTicks FromAndroidTime(int64 time_ms) { | 74 base::TimeTicks FromAndroidTime(int64 time_ms) { |
37 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms); | 75 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms); |
38 } | 76 } |
39 | 77 |
40 } // namespace | 78 } // namespace |
41 | 79 |
42 MotionEventAndroid::MotionEventAndroid(jobject event) | 80 MotionEventAndroid::MotionEventAndroid(JNIEnv* env, jobject event, bool recycle) |
43 : should_recycle_(false) { | 81 : cached_time_(FromAndroidTime(Java_MotionEvent_getEventTime(env, event))), |
44 event_.Reset(AttachCurrentThread(), event); | 82 cached_action_(FromAndroidAction( |
| 83 Java_MotionEvent_getActionMasked(env, event))), |
| 84 cached_pointer_count_(Java_MotionEvent_getPointerCount(env, event)), |
| 85 cached_history_size_(Java_MotionEvent_getHistorySize(env, event)), |
| 86 cached_action_index_(Java_MotionEvent_getActionIndex(env, event)), |
| 87 cached_x_(Java_MotionEvent_getXF(env, event)), |
| 88 cached_y_(Java_MotionEvent_getYF(env, event)), |
| 89 should_recycle_(recycle) { |
| 90 event_.Reset(env, event); |
45 DCHECK(event_.obj()); | 91 DCHECK(event_.obj()); |
46 } | 92 } |
47 | 93 |
48 MotionEventAndroid::MotionEventAndroid( | 94 MotionEventAndroid::MotionEventAndroid(const MotionEventAndroid& other, |
49 const base::android::ScopedJavaLocalRef<jobject>& event, | 95 bool clone) |
50 bool should_recycle) | 96 : cached_time_(other.cached_time_), |
51 : event_(event), | 97 cached_action_(other.cached_action_), |
52 should_recycle_(should_recycle) { | 98 cached_pointer_count_(other.cached_pointer_count_), |
53 DCHECK(event_.obj()); | 99 cached_history_size_(other.cached_history_size_), |
| 100 cached_action_index_(other.cached_action_index_), |
| 101 cached_x_(other.cached_x_), |
| 102 cached_y_(other.cached_y_), |
| 103 should_recycle_(clone) { |
| 104 // An event with a pending recycle should never be copied (only cloned). |
| 105 DCHECK(clone || !other.should_recycle_); |
| 106 if (clone) |
| 107 event_.Reset(Obtain(other)); |
| 108 else |
| 109 event_.Reset(other.event_); |
54 } | 110 } |
55 | 111 |
56 MotionEventAndroid::~MotionEventAndroid() { | 112 MotionEventAndroid::~MotionEventAndroid() { |
57 if (should_recycle_) | 113 if (should_recycle_) |
58 Java_MotionEvent_recycle(AttachCurrentThread(), event_.obj()); | 114 Java_MotionEvent_recycle(AttachCurrentThread(), event_.obj()); |
59 } | 115 } |
60 | 116 |
61 MotionEventAndroid::Action MotionEventAndroid::GetActionMasked() const { | 117 MotionEventAndroid::Action MotionEventAndroid::GetAction() const { |
62 return FromAndroidAction( | 118 return cached_action_; |
63 Java_MotionEvent_getActionMasked(AttachCurrentThread(), event_.obj())); | |
64 } | 119 } |
65 | 120 |
66 size_t MotionEventAndroid::GetActionIndex() const { | 121 int MotionEventAndroid::GetActionIndex() const { |
67 return Java_MotionEvent_getActionIndex(AttachCurrentThread(), event_.obj()); | 122 return cached_action_index_; |
68 } | 123 } |
69 | 124 |
70 size_t MotionEventAndroid::GetPointerCount() const { | 125 size_t MotionEventAndroid::GetPointerCount() const { |
71 return Java_MotionEvent_getPointerCount(AttachCurrentThread(), event_.obj()); | 126 return cached_pointer_count_; |
72 } | 127 } |
73 | 128 |
74 int MotionEventAndroid::GetPointerId(size_t pointer_index) const { | 129 int MotionEventAndroid::GetPointerId(size_t pointer_index) const { |
| 130 DCHECK_LT(pointer_index, cached_pointer_count_); |
75 return Java_MotionEvent_getPointerId( | 131 return Java_MotionEvent_getPointerId( |
76 AttachCurrentThread(), event_.obj(), pointer_index); | 132 AttachCurrentThread(), event_.obj(), pointer_index); |
77 } | 133 } |
78 | 134 |
79 float MotionEventAndroid::GetPressure(size_t pointer_index) const { | |
80 return Java_MotionEvent_getPressureF_I( | |
81 AttachCurrentThread(), event_.obj(), pointer_index); | |
82 } | |
83 | |
84 float MotionEventAndroid::GetX(size_t pointer_index) const { | 135 float MotionEventAndroid::GetX(size_t pointer_index) const { |
| 136 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 137 if (pointer_index == 0) |
| 138 return cached_x_; |
85 return Java_MotionEvent_getXF_I( | 139 return Java_MotionEvent_getXF_I( |
86 AttachCurrentThread(), event_.obj(), pointer_index); | 140 AttachCurrentThread(), event_.obj(), pointer_index); |
87 } | 141 } |
88 | 142 |
89 float MotionEventAndroid::GetY(size_t pointer_index) const { | 143 float MotionEventAndroid::GetY(size_t pointer_index) const { |
| 144 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 145 if (pointer_index == 0) |
| 146 return cached_y_; |
90 return Java_MotionEvent_getYF_I( | 147 return Java_MotionEvent_getYF_I( |
91 AttachCurrentThread(), event_.obj(), pointer_index); | 148 AttachCurrentThread(), event_.obj(), pointer_index); |
92 } | 149 } |
93 | 150 |
94 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const { | 151 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const { |
| 152 DCHECK_LT(pointer_index, cached_pointer_count_); |
95 return Java_MotionEvent_getTouchMajorF_I( | 153 return Java_MotionEvent_getTouchMajorF_I( |
96 AttachCurrentThread(), event_.obj(), pointer_index); | 154 AttachCurrentThread(), event_.obj(), pointer_index); |
97 } | 155 } |
98 | 156 |
99 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const { | |
100 return Java_MotionEvent_getTouchMinorF_I( | |
101 AttachCurrentThread(), event_.obj(), pointer_index); | |
102 } | |
103 | |
104 float MotionEventAndroid::GetOrientation() const { | |
105 return Java_MotionEvent_getOrientationF(AttachCurrentThread(), event_.obj()); | |
106 } | |
107 | |
108 base::TimeTicks MotionEventAndroid::GetEventTime() const { | 157 base::TimeTicks MotionEventAndroid::GetEventTime() const { |
109 return FromAndroidTime( | 158 return cached_time_; |
110 Java_MotionEvent_getEventTime(AttachCurrentThread(), event_.obj())); | |
111 } | |
112 | |
113 base::TimeTicks MotionEventAndroid::GetDownTime() const { | |
114 return FromAndroidTime( | |
115 Java_MotionEvent_getDownTime(AttachCurrentThread(), event_.obj())); | |
116 } | 159 } |
117 | 160 |
118 size_t MotionEventAndroid::GetHistorySize() const { | 161 size_t MotionEventAndroid::GetHistorySize() const { |
119 return Java_MotionEvent_getHistorySize(AttachCurrentThread(), event_.obj()); | 162 return cached_history_size_; |
120 } | 163 } |
121 | 164 |
122 base::TimeTicks MotionEventAndroid::GetHistoricalEventTime( | 165 base::TimeTicks MotionEventAndroid::GetHistoricalEventTime( |
123 size_t historical_index) const { | 166 size_t historical_index) const { |
124 return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime( | 167 return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime( |
125 AttachCurrentThread(), event_.obj(), historical_index)); | 168 AttachCurrentThread(), event_.obj(), historical_index)); |
126 } | 169 } |
127 | 170 |
128 float MotionEventAndroid::GetHistoricalTouchMajor(size_t pointer_index, | 171 float MotionEventAndroid::GetHistoricalTouchMajor(size_t pointer_index, |
129 size_t historical_index) | 172 size_t historical_index) |
130 const { | 173 const { |
131 return Java_MotionEvent_getHistoricalTouchMajorF_I_I( | 174 return Java_MotionEvent_getHistoricalTouchMajorF_I_I( |
132 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); | 175 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); |
133 } | 176 } |
134 | 177 |
135 float MotionEventAndroid::GetHistoricalX(size_t pointer_index, | 178 float MotionEventAndroid::GetHistoricalX(size_t pointer_index, |
136 size_t historical_index) const { | 179 size_t historical_index) const { |
137 return Java_MotionEvent_getHistoricalXF_I_I( | 180 return Java_MotionEvent_getHistoricalXF_I_I( |
138 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); | 181 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); |
139 } | 182 } |
140 | 183 |
141 float MotionEventAndroid::GetHistoricalY(size_t pointer_index, | 184 float MotionEventAndroid::GetHistoricalY(size_t pointer_index, |
142 size_t historical_index) const { | 185 size_t historical_index) const { |
143 return Java_MotionEvent_getHistoricalYF_I_I( | 186 return Java_MotionEvent_getHistoricalYF_I_I( |
144 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); | 187 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); |
145 } | 188 } |
146 | 189 |
| 190 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Clone() const { |
| 191 return scoped_ptr<MotionEvent>(new MotionEventAndroid(*this, true)); |
| 192 } |
| 193 |
| 194 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Cancel() const { |
| 195 return scoped_ptr<MotionEvent>(new MotionEventAndroid( |
| 196 AttachCurrentThread(), |
| 197 Obtain(GetDownTime(), |
| 198 GetEventTime(), |
| 199 ACTION_CANCEL, |
| 200 GetX(0), |
| 201 GetY(0)).obj(), |
| 202 true)); |
| 203 } |
| 204 |
| 205 float MotionEventAndroid::GetPressure(size_t pointer_index) const { |
| 206 return Java_MotionEvent_getPressureF_I( |
| 207 AttachCurrentThread(), event_.obj(), pointer_index); |
| 208 } |
| 209 |
| 210 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const { |
| 211 return Java_MotionEvent_getTouchMinorF_I( |
| 212 AttachCurrentThread(), event_.obj(), pointer_index); |
| 213 } |
| 214 |
| 215 float MotionEventAndroid::GetOrientation() const { |
| 216 return Java_MotionEvent_getOrientationF(AttachCurrentThread(), event_.obj()); |
| 217 } |
| 218 |
| 219 base::TimeTicks MotionEventAndroid::GetDownTime() const { |
| 220 return FromAndroidTime( |
| 221 Java_MotionEvent_getDownTime(AttachCurrentThread(), event_.obj())); |
| 222 } |
| 223 |
147 // static | 224 // static |
148 bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) { | 225 bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) { |
149 return JNI_MotionEvent::RegisterNativesImpl(env); | 226 return JNI_MotionEvent::RegisterNativesImpl(env); |
150 } | 227 } |
151 | 228 |
152 // static | 229 // static |
153 scoped_ptr<MotionEventAndroid> MotionEventAndroid::Obtain( | 230 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain( |
154 const MotionEventAndroid& event) { | 231 const MotionEventAndroid& event) { |
155 return make_scoped_ptr(new MotionEventAndroid( | 232 return Java_MotionEvent_obtainAVME_AVME(AttachCurrentThread(), |
156 Java_MotionEvent_obtainAVME_AVME(AttachCurrentThread(), | 233 event.event_.obj()); |
157 event.event_.obj()), | |
158 true)); | |
159 } | 234 } |
160 | 235 |
161 // static | 236 // static |
162 scoped_ptr<MotionEventAndroid> MotionEventAndroid::Obtain( | 237 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain( |
163 base::TimeTicks down_time, | 238 base::TimeTicks down_time, |
164 base::TimeTicks event__time, | 239 base::TimeTicks event_time, |
165 Action action, | 240 Action action, |
166 float x, | 241 float x, |
167 float y) { | 242 float y) { |
168 return make_scoped_ptr(new MotionEventAndroid( | 243 return Java_MotionEvent_obtainAVME_J_J_I_F_F_I(AttachCurrentThread(), |
169 Java_MotionEvent_obtainAVME_J_J_I_F_F_I(AttachCurrentThread(), | 244 ToAndroidTime(down_time), |
170 ToAndroidTime(down_time), | 245 ToAndroidTime(event_time), |
171 ToAndroidTime(down_time), | 246 ToAndroidAction(action), |
172 action, | 247 x, |
173 x, | 248 y, |
174 y, | 249 0); |
175 0), | |
176 true)); | |
177 } | 250 } |
178 | 251 |
179 } // namespace content | 252 } // namespace content |
OLD | NEW |