Home | History | Annotate | Download | only in android
      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