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