Chromium Code Reviews| 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 #include "ui/gfx/android/device_display_info.h" | |
| 9 | 10 |
| 10 using base::android::AttachCurrentThread; | 11 using base::android::AttachCurrentThread; |
| 11 using namespace JNI_MotionEvent; | 12 using namespace JNI_MotionEvent; |
| 12 | 13 |
| 13 namespace content { | 14 namespace content { |
| 14 namespace { | 15 namespace { |
| 15 | 16 |
| 16 int ToAndroidAction(MotionEventAndroid::Action action) { | 17 int ToAndroidAction(MotionEventAndroid::Action action) { |
| 17 switch (action) { | 18 switch (action) { |
| 18 case MotionEventAndroid::ACTION_DOWN: | 19 case MotionEventAndroid::ACTION_DOWN: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 int64 ToAndroidTime(base::TimeTicks time) { | 58 int64 ToAndroidTime(base::TimeTicks time) { |
| 58 return (time - base::TimeTicks()).InMilliseconds(); | 59 return (time - base::TimeTicks()).InMilliseconds(); |
| 59 } | 60 } |
| 60 | 61 |
| 61 base::TimeTicks FromAndroidTime(int64 time_ms) { | 62 base::TimeTicks FromAndroidTime(int64 time_ms) { |
| 62 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms); | 63 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms); |
| 63 } | 64 } |
| 64 | 65 |
| 65 } // namespace | 66 } // namespace |
| 66 | 67 |
| 67 MotionEventAndroid::MotionEventAndroid(JNIEnv* env, | 68 MotionEventAndroid::MotionEventAndroid(float px_to_dp, |
| 69 JNIEnv* env, | |
| 68 jobject event, | 70 jobject event, |
| 69 jlong time_ms, | 71 jlong time_ms, |
| 70 jint android_action, | 72 jint android_action, |
| 71 jint pointer_count, | 73 jint pointer_count, |
| 72 jint history_size, | 74 jint history_size, |
| 73 jint action_index, | 75 jint action_index, |
| 74 jfloat pos_x_0, | 76 jfloat pos_x_0_pixels, |
| 75 jfloat pos_y_0, | 77 jfloat pos_y_0_pixels, |
| 76 jfloat pos_x_1, | 78 jfloat pos_x_1_pixels, |
| 77 jfloat pos_y_1, | 79 jfloat pos_y_1_pixels, |
| 78 jint pointer_id_0, | 80 jint pointer_id_0, |
| 79 jint pointer_id_1, | 81 jint pointer_id_1, |
| 80 jfloat touch_major_0, | 82 jfloat touch_major_0_pixels, |
| 81 jfloat touch_major_1) | 83 jfloat touch_major_1_pixels) |
| 82 : cached_time_(FromAndroidTime(time_ms)), | 84 : cached_time_(FromAndroidTime(time_ms)), |
| 83 cached_action_(FromAndroidAction(android_action)), | 85 cached_action_(FromAndroidAction(android_action)), |
| 84 cached_pointer_count_(pointer_count), | 86 cached_pointer_count_(pointer_count), |
| 85 cached_history_size_(history_size), | 87 cached_history_size_(history_size), |
| 86 cached_action_index_(action_index), | 88 cached_action_index_(action_index), |
| 89 px_to_dp_(px_to_dp), | |
| 87 should_recycle_(false) { | 90 should_recycle_(false) { |
| 88 DCHECK_GT(pointer_count, 0); | 91 DCHECK_GT(pointer_count, 0); |
| 89 DCHECK_GE(history_size, 0); | 92 DCHECK_GE(history_size, 0); |
| 90 | 93 |
| 91 event_.Reset(env, event); | 94 event_.Reset(env, event); |
| 92 DCHECK(event_.obj()); | 95 DCHECK(event_.obj()); |
| 93 | 96 |
| 94 cached_positions_[0] = gfx::PointF(pos_x_0, pos_y_0); | 97 cached_positions_[0] = ToDips(gfx::PointF(pos_x_0_pixels, pos_y_0_pixels)); |
| 95 cached_positions_[1] = gfx::PointF(pos_x_1, pos_y_1); | 98 cached_positions_[1] = ToDips(gfx::PointF(pos_x_1_pixels, pos_y_1_pixels)); |
| 96 cached_pointer_ids_[0] = pointer_id_0; | 99 cached_pointer_ids_[0] = pointer_id_0; |
| 97 cached_pointer_ids_[1] = pointer_id_1; | 100 cached_pointer_ids_[1] = pointer_id_1; |
| 98 cached_touch_majors_[0] = touch_major_0; | 101 cached_touch_majors_[0] = ToDips(touch_major_0_pixels); |
| 99 cached_touch_majors_[1] = touch_major_1; | 102 cached_touch_majors_[1] = ToDips(touch_major_1_pixels); |
| 100 } | 103 } |
| 101 | 104 |
| 102 MotionEventAndroid::MotionEventAndroid(JNIEnv* env, jobject event) | 105 MotionEventAndroid::MotionEventAndroid(JNIEnv* env, jobject event) |
| 103 : cached_time_(FromAndroidTime(Java_MotionEvent_getEventTime(env, event))), | 106 : cached_time_(FromAndroidTime(Java_MotionEvent_getEventTime(env, event))), |
| 104 cached_action_(FromAndroidAction( | 107 cached_action_( |
| 105 Java_MotionEvent_getActionMasked(env, event))), | 108 FromAndroidAction(Java_MotionEvent_getActionMasked(env, event))), |
| 106 cached_pointer_count_(Java_MotionEvent_getPointerCount(env, event)), | 109 cached_pointer_count_(Java_MotionEvent_getPointerCount(env, event)), |
| 107 cached_history_size_(Java_MotionEvent_getHistorySize(env, event)), | 110 cached_history_size_(Java_MotionEvent_getHistorySize(env, event)), |
| 108 cached_action_index_(Java_MotionEvent_getActionIndex(env, event)), | 111 cached_action_index_(Java_MotionEvent_getActionIndex(env, event)), |
| 112 px_to_dp_(1.f / gfx::DeviceDisplayInfo().GetDIPScale()), | |
| 109 should_recycle_(true) { | 113 should_recycle_(true) { |
| 110 event_.Reset(env, event); | 114 event_.Reset(env, event); |
| 111 DCHECK(event_.obj()); | 115 DCHECK(event_.obj()); |
| 112 | 116 |
| 113 for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) { | 117 for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) { |
| 114 if (i < cached_pointer_count_) { | 118 if (i < cached_pointer_count_) { |
| 115 cached_positions_[i].set_x(Java_MotionEvent_getXF_I(env, event, i)); | 119 cached_positions_[i] = |
| 116 cached_positions_[i].set_y(Java_MotionEvent_getYF_I(env, event, i)); | 120 ToDips(gfx::PointF(Java_MotionEvent_getXF_I(env, event, i), |
| 121 Java_MotionEvent_getYF_I(env, event, i))); | |
| 117 cached_pointer_ids_[i] = Java_MotionEvent_getPointerId(env, event, i); | 122 cached_pointer_ids_[i] = Java_MotionEvent_getPointerId(env, event, i); |
| 118 cached_touch_majors_[i] = | 123 cached_touch_majors_[i] = |
| 119 Java_MotionEvent_getTouchMajorF_I(env, event, i); | 124 ToDips(Java_MotionEvent_getTouchMajorF_I(env, event, i)); |
| 120 } else { | 125 } else { |
| 121 cached_pointer_ids_[i] = 0; | 126 cached_pointer_ids_[i] = 0; |
| 122 cached_touch_majors_[i] = 0.f; | 127 cached_touch_majors_[i] = 0.f; |
| 123 } | 128 } |
| 124 } | 129 } |
| 125 } | 130 } |
| 126 | 131 |
| 127 MotionEventAndroid::MotionEventAndroid(const MotionEventAndroid& other) | 132 MotionEventAndroid::MotionEventAndroid(const MotionEventAndroid& other) |
| 128 : event_(Obtain(other)), | 133 : event_(Obtain(other)), |
| 129 cached_time_(other.cached_time_), | 134 cached_time_(other.cached_time_), |
| 130 cached_action_(other.cached_action_), | 135 cached_action_(other.cached_action_), |
| 131 cached_pointer_count_(other.cached_pointer_count_), | 136 cached_pointer_count_(other.cached_pointer_count_), |
| 132 cached_history_size_(other.cached_history_size_), | 137 cached_history_size_(other.cached_history_size_), |
| 133 cached_action_index_(other.cached_action_index_), | 138 cached_action_index_(other.cached_action_index_), |
| 139 px_to_dp_(other.px_to_dp_), | |
| 134 should_recycle_(true) { | 140 should_recycle_(true) { |
| 135 DCHECK(event_.obj()); | 141 DCHECK(event_.obj()); |
| 136 for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) { | 142 for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) { |
| 137 cached_positions_[i] = other.cached_positions_[i]; | 143 cached_positions_[i] = other.cached_positions_[i]; |
| 138 cached_pointer_ids_[i] = other.cached_pointer_ids_[i]; | 144 cached_pointer_ids_[i] = other.cached_pointer_ids_[i]; |
| 139 cached_touch_majors_[i] = other.cached_touch_majors_[i]; | 145 cached_touch_majors_[i] = other.cached_touch_majors_[i]; |
| 140 } | 146 } |
| 141 } | 147 } |
| 142 | 148 |
| 143 MotionEventAndroid::~MotionEventAndroid() { | 149 MotionEventAndroid::~MotionEventAndroid() { |
| 144 if (should_recycle_) | 150 if (should_recycle_) |
| 145 Java_MotionEvent_recycle(AttachCurrentThread(), event_.obj()); | 151 Java_MotionEvent_recycle(AttachCurrentThread(), event_.obj()); |
| 146 } | 152 } |
| 147 | 153 |
| 148 int MotionEventAndroid::GetId() const { | 154 int MotionEventAndroid::GetId() const { |
| 149 return 0; | 155 return 0; |
| 150 } | 156 } |
| 151 | 157 |
| 152 MotionEventAndroid::Action MotionEventAndroid::GetAction() const { | 158 MotionEventAndroid::Action MotionEventAndroid::GetAction() const { |
| 153 return cached_action_; | 159 return cached_action_; |
| 154 } | 160 } |
| 155 | 161 |
| 156 int MotionEventAndroid::GetActionIndex() const { | 162 int MotionEventAndroid::GetActionIndex() const { return cached_action_index_; } |
| 157 return cached_action_index_; | |
| 158 } | |
| 159 | 163 |
| 160 size_t MotionEventAndroid::GetPointerCount() const { | 164 size_t MotionEventAndroid::GetPointerCount() const { |
| 161 return cached_pointer_count_; | 165 return cached_pointer_count_; |
| 162 } | 166 } |
| 163 | 167 |
| 164 int MotionEventAndroid::GetPointerId(size_t pointer_index) const { | 168 int MotionEventAndroid::GetPointerId(size_t pointer_index) const { |
| 165 DCHECK_LT(pointer_index, cached_pointer_count_); | 169 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 166 if (pointer_index < MAX_POINTERS_TO_CACHE) | 170 if (pointer_index < MAX_POINTERS_TO_CACHE) |
| 167 return cached_pointer_ids_[pointer_index]; | 171 return cached_pointer_ids_[pointer_index]; |
| 168 return Java_MotionEvent_getPointerId( | 172 return Java_MotionEvent_getPointerId( |
| 169 AttachCurrentThread(), event_.obj(), pointer_index); | 173 AttachCurrentThread(), event_.obj(), pointer_index); |
| 170 } | 174 } |
| 171 | 175 |
| 172 float MotionEventAndroid::GetX(size_t pointer_index) const { | 176 float MotionEventAndroid::GetX(size_t pointer_index) const { |
| 173 DCHECK_LT(pointer_index, cached_pointer_count_); | 177 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 174 if (pointer_index < MAX_POINTERS_TO_CACHE) | 178 if (pointer_index < MAX_POINTERS_TO_CACHE) |
| 175 return cached_positions_[pointer_index].x(); | 179 return cached_positions_[pointer_index].x(); |
| 176 return Java_MotionEvent_getXF_I( | 180 return ToDips(Java_MotionEvent_getXF_I( |
| 177 AttachCurrentThread(), event_.obj(), pointer_index); | 181 AttachCurrentThread(), event_.obj(), pointer_index)); |
| 178 } | 182 } |
| 179 | 183 |
| 180 float MotionEventAndroid::GetY(size_t pointer_index) const { | 184 float MotionEventAndroid::GetY(size_t pointer_index) const { |
| 181 DCHECK_LT(pointer_index, cached_pointer_count_); | 185 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 182 if (pointer_index < MAX_POINTERS_TO_CACHE) | 186 if (pointer_index < MAX_POINTERS_TO_CACHE) |
| 183 return cached_positions_[pointer_index].y(); | 187 return cached_positions_[pointer_index].y(); |
| 184 return Java_MotionEvent_getYF_I( | 188 return ToDips(Java_MotionEvent_getYF_I( |
| 185 AttachCurrentThread(), event_.obj(), pointer_index); | 189 AttachCurrentThread(), event_.obj(), pointer_index)); |
| 186 } | 190 } |
| 187 | 191 |
| 188 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const { | 192 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const { |
| 189 DCHECK_LT(pointer_index, cached_pointer_count_); | 193 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 190 if (pointer_index < MAX_POINTERS_TO_CACHE) | 194 if (pointer_index < MAX_POINTERS_TO_CACHE) |
| 191 return cached_touch_majors_[pointer_index]; | 195 return cached_touch_majors_[pointer_index]; |
| 192 return Java_MotionEvent_getTouchMajorF_I( | 196 return ToDips(Java_MotionEvent_getTouchMajorF_I( |
| 193 AttachCurrentThread(), event_.obj(), pointer_index); | 197 AttachCurrentThread(), event_.obj(), pointer_index)); |
| 194 } | 198 } |
| 195 | 199 |
| 196 float MotionEventAndroid::GetPressure(size_t pointer_index) const { | 200 float MotionEventAndroid::GetPressure(size_t pointer_index) const { |
| 197 DCHECK_LT(pointer_index, cached_pointer_count_); | 201 DCHECK_LT(pointer_index, cached_pointer_count_); |
| 198 return Java_MotionEvent_getPressureF_I( | 202 return Java_MotionEvent_getPressureF_I( |
| 199 AttachCurrentThread(), event_.obj(), pointer_index); | 203 AttachCurrentThread(), event_.obj(), pointer_index); |
| 200 } | 204 } |
| 201 | 205 |
| 202 base::TimeTicks MotionEventAndroid::GetEventTime() const { | 206 base::TimeTicks MotionEventAndroid::GetEventTime() const { |
| 203 return cached_time_; | 207 return cached_time_; |
| 204 } | 208 } |
| 205 | 209 |
| 206 size_t MotionEventAndroid::GetHistorySize() const { | 210 size_t MotionEventAndroid::GetHistorySize() const { |
| 207 return cached_history_size_; | 211 return cached_history_size_; |
| 208 } | 212 } |
| 209 | 213 |
| 210 base::TimeTicks MotionEventAndroid::GetHistoricalEventTime( | 214 base::TimeTicks MotionEventAndroid::GetHistoricalEventTime( |
| 211 size_t historical_index) const { | 215 size_t historical_index) const { |
| 212 return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime( | 216 return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime( |
| 213 AttachCurrentThread(), event_.obj(), historical_index)); | 217 AttachCurrentThread(), event_.obj(), historical_index)); |
| 214 } | 218 } |
| 215 | 219 |
| 216 float MotionEventAndroid::GetHistoricalTouchMajor(size_t pointer_index, | 220 float MotionEventAndroid::GetHistoricalTouchMajor( |
| 217 size_t historical_index) | 221 size_t pointer_index, |
| 218 const { | 222 size_t historical_index) const { |
| 219 return Java_MotionEvent_getHistoricalTouchMajorF_I_I( | 223 return ToDips(Java_MotionEvent_getHistoricalTouchMajorF_I_I( |
| 220 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); | 224 AttachCurrentThread(), event_.obj(), pointer_index, historical_index)); |
| 221 } | 225 } |
| 222 | 226 |
| 223 float MotionEventAndroid::GetHistoricalX(size_t pointer_index, | 227 float MotionEventAndroid::GetHistoricalX(size_t pointer_index, |
| 224 size_t historical_index) const { | 228 size_t historical_index) const { |
| 225 return Java_MotionEvent_getHistoricalXF_I_I( | 229 return ToDips(Java_MotionEvent_getHistoricalXF_I_I( |
| 226 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); | 230 AttachCurrentThread(), event_.obj(), pointer_index, historical_index)); |
| 227 } | 231 } |
| 228 | 232 |
| 229 float MotionEventAndroid::GetHistoricalY(size_t pointer_index, | 233 float MotionEventAndroid::GetHistoricalY(size_t pointer_index, |
| 230 size_t historical_index) const { | 234 size_t historical_index) const { |
| 231 return Java_MotionEvent_getHistoricalYF_I_I( | 235 return ToDips(Java_MotionEvent_getHistoricalYF_I_I( |
| 232 AttachCurrentThread(), event_.obj(), pointer_index, historical_index); | 236 AttachCurrentThread(), event_.obj(), pointer_index, historical_index)); |
| 233 } | 237 } |
| 234 | 238 |
| 235 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Clone() const { | 239 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Clone() const { |
| 236 return scoped_ptr<MotionEvent>(new MotionEventAndroid(*this)); | 240 return scoped_ptr<MotionEvent>(new MotionEventAndroid(*this)); |
| 237 } | 241 } |
| 238 | 242 |
| 239 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Cancel() const { | 243 scoped_ptr<ui::MotionEvent> MotionEventAndroid::Cancel() const { |
| 240 return scoped_ptr<MotionEvent>(new MotionEventAndroid( | 244 return scoped_ptr<MotionEvent>( |
| 241 AttachCurrentThread(), | 245 new MotionEventAndroid(AttachCurrentThread(), |
| 242 Obtain(GetDownTime(), | 246 Obtain(GetDownTime(), |
| 243 GetEventTime(), | 247 GetEventTime(), |
| 244 MotionEventAndroid::ACTION_CANCEL, | 248 MotionEventAndroid::ACTION_CANCEL, |
| 245 GetX(0), | 249 GetX(0) / px_to_dp_, |
|
tdresser
2014/04/09 14:00:01
I guess caching the coordinates in pixels to avoid
jdduke (slow)
2014/04/10 22:04:53
|Cancel()| should be called relatively infrequentl
| |
| 246 GetY(0)).obj())); | 250 GetY(0) / px_to_dp_).obj())); |
| 247 } | 251 } |
| 248 | 252 |
| 249 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const { | 253 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const { |
| 250 return Java_MotionEvent_getTouchMinorF_I( | 254 return ToDips(Java_MotionEvent_getTouchMinorF_I( |
| 251 AttachCurrentThread(), event_.obj(), pointer_index); | 255 AttachCurrentThread(), event_.obj(), pointer_index)); |
| 252 } | 256 } |
| 253 | 257 |
| 254 float MotionEventAndroid::GetOrientation() const { | 258 float MotionEventAndroid::GetOrientation() const { |
| 255 return Java_MotionEvent_getOrientationF(AttachCurrentThread(), event_.obj()); | 259 return Java_MotionEvent_getOrientationF(AttachCurrentThread(), event_.obj()); |
| 256 } | 260 } |
| 257 | 261 |
| 258 base::TimeTicks MotionEventAndroid::GetDownTime() const { | 262 base::TimeTicks MotionEventAndroid::GetDownTime() const { |
| 259 return FromAndroidTime( | 263 return FromAndroidTime( |
| 260 Java_MotionEvent_getDownTime(AttachCurrentThread(), event_.obj())); | 264 Java_MotionEvent_getDownTime(AttachCurrentThread(), event_.obj())); |
| 261 } | 265 } |
| 262 | 266 |
| 267 float MotionEventAndroid::ToDips(float pixels) const { | |
| 268 return pixels * px_to_dp_; | |
| 269 } | |
| 270 | |
| 271 gfx::PointF MotionEventAndroid::ToDips(const gfx::PointF& point_pixels) const { | |
| 272 return gfx::ScalePoint(point_pixels, px_to_dp_); | |
| 273 } | |
| 274 | |
| 263 // static | 275 // static |
| 264 bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) { | 276 bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) { |
| 265 return JNI_MotionEvent::RegisterNativesImpl(env); | 277 return JNI_MotionEvent::RegisterNativesImpl(env); |
| 266 } | 278 } |
| 267 | 279 |
| 268 // static | 280 // static |
| 269 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain( | 281 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain( |
| 270 const MotionEventAndroid& event) { | 282 const MotionEventAndroid& event) { |
| 271 return Java_MotionEvent_obtainAVME_AVME(AttachCurrentThread(), | 283 return Java_MotionEvent_obtainAVME_AVME(AttachCurrentThread(), |
| 272 event.event_.obj()); | 284 event.event_.obj()); |
| 273 } | 285 } |
| 274 | 286 |
| 275 // static | 287 // static |
| 276 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain( | 288 base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain( |
| 277 base::TimeTicks down_time, | 289 base::TimeTicks down_time, |
| 278 base::TimeTicks event_time, | 290 base::TimeTicks event_time, |
| 279 Action action, | 291 Action action, |
| 280 float x, | 292 float x_pixels, |
| 281 float y) { | 293 float y_pixels) { |
| 282 return Java_MotionEvent_obtainAVME_J_J_I_F_F_I(AttachCurrentThread(), | 294 return Java_MotionEvent_obtainAVME_J_J_I_F_F_I(AttachCurrentThread(), |
| 283 ToAndroidTime(down_time), | 295 ToAndroidTime(down_time), |
| 284 ToAndroidTime(event_time), | 296 ToAndroidTime(event_time), |
| 285 ToAndroidAction(action), | 297 ToAndroidAction(action), |
| 286 x, | 298 x_pixels, |
| 287 y, | 299 y_pixels, |
| 288 0); | 300 0); |
| 289 } | 301 } |
| 290 | 302 |
| 291 } // namespace content | 303 } // namespace content |
| OLD | NEW |