1 // Copyright (c) 2012 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/android/touch_point.h" 6 7 #include "base/debug/debugger.h" 8 #include "base/logging.h" 9 #include "base/time/time.h" 10 11 #include "jni/TouchPoint_jni.h" 12 13 using blink::WebTouchEvent; 14 using blink::WebTouchPoint; 15 16 namespace { 17 18 void MaybeAddTouchPoint(JNIEnv* env, 19 jobject pt, 20 float dpi_scale, 21 blink::WebTouchEvent& event) { 22 WebTouchPoint::State state = static_cast<WebTouchPoint::State>( 23 Java_TouchPoint_getState(env, pt)); 24 if (state == WebTouchPoint::StateUndefined) 25 return; 26 27 // When generating a cancel event from an event of a different type, the 28 // touch points are out of sync, so we ensure the points are marked as 29 // canceled as well. 30 if (event.type == WebTouchEvent::TouchCancel) 31 state = WebTouchPoint::StateCancelled; 32 33 // Record the current number of points in the WebTouchEvent 34 const int idx = event.touchesLength; 35 DCHECK_LT(idx, blink::WebTouchEvent::touchesLengthCap); 36 37 WebTouchPoint wtp; 38 wtp.id = Java_TouchPoint_getId(env, pt); 39 wtp.state = state; 40 wtp.position.x = Java_TouchPoint_getX(env, pt) / dpi_scale; 41 wtp.position.y = Java_TouchPoint_getY(env, pt) / dpi_scale; 42 // TODO(joth): Raw event co-ordinates. 43 wtp.screenPosition = wtp.position; 44 wtp.force = Java_TouchPoint_getPressure(env, pt); 45 46 const int radiusMajor = static_cast<int>( 47 Java_TouchPoint_getTouchMajor(env, pt) * 0.5f / dpi_scale); 48 const int radiusMinor = static_cast<int>( 49 Java_TouchPoint_getTouchMinor(env, pt) * 0.5f / dpi_scale); 50 const float majorAngleInRadiansClockwiseFromVertical = 51 Java_TouchPoint_getOrientation(env, pt); 52 const float majorAngleInDegreesClockwiseFromVertical = 53 std::isnan(majorAngleInRadiansClockwiseFromVertical) 54 ? 0.f : (majorAngleInRadiansClockwiseFromVertical * 180.f) / M_PI; 55 // Android provides a major axis orientation clockwise with respect to the 56 // vertical of [-90, 90], while the W3C specifies a range of [0, 90]. 57 if (majorAngleInDegreesClockwiseFromVertical >= 0) { 58 wtp.radiusX = radiusMinor; 59 wtp.radiusY = radiusMajor; 60 wtp.rotationAngle = majorAngleInDegreesClockwiseFromVertical; 61 } else { 62 wtp.radiusX = radiusMajor; 63 wtp.radiusY = radiusMinor; 64 wtp.rotationAngle = majorAngleInDegreesClockwiseFromVertical + 90.f; 65 } 66 DCHECK_GE(wtp.rotationAngle, 0.f); 67 DCHECK_LE(wtp.rotationAngle, 90.f); 68 69 // Add the newly created WebTouchPoint to the event 70 event.touches[idx] = wtp; 71 ++(event.touchesLength); 72 } 73 74 } // namespace 75 76 namespace content { 77 78 void TouchPoint::BuildWebTouchEvent(JNIEnv* env, 79 jint type, 80 jlong time_ms, 81 float dpi_scale, 82 jobjectArray pts, 83 blink::WebTouchEvent& event) { 84 event.type = static_cast<WebTouchEvent::Type>(type); 85 event.timeStampSeconds = 86 static_cast<double>(time_ms) / base::Time::kMillisecondsPerSecond; 87 int arrayLength = env->GetArrayLength(pts); 88 // Loop until either all of the input points have been consumed or the output 89 // array has been filled 90 for (int i = 0; i < arrayLength; i++) { 91 jobject pt = env->GetObjectArrayElement(pts, i); 92 MaybeAddTouchPoint(env, pt, dpi_scale, event); 93 if (event.touchesLength >= event.touchesLengthCap) 94 break; 95 } 96 DCHECK_GT(event.touchesLength, 0U); 97 } 98 99 static void RegisterConstants(JNIEnv* env) { 100 Java_TouchPoint_initializeConstants( 101 env, 102 blink::WebTouchEvent::TouchStart, 103 blink::WebTouchEvent::TouchMove, 104 blink::WebTouchEvent::TouchEnd, 105 blink::WebTouchEvent::TouchCancel, 106 blink::WebTouchPoint::StateUndefined, 107 blink::WebTouchPoint::StateReleased, 108 blink::WebTouchPoint::StatePressed, 109 blink::WebTouchPoint::StateMoved, 110 blink::WebTouchPoint::StateStationary, 111 blink::WebTouchPoint::StateCancelled); 112 } 113 114 bool RegisterTouchPoint(JNIEnv* env) { 115 if (!RegisterNativesImpl(env)) 116 return false; 117 118 RegisterConstants(env); 119 120 return true; 121 } 122 123 } // namespace content 124